1.首先,你得理解Unity中各個目錄的意思?
我這里說的是移動平臺(安卓舉例),讀,寫。所謂讀,就是你出大版本的包之后,這個只讀的話,就一輩子就這些東西了,不會改變了,不會有其他資源來覆蓋或者增加啦。
可寫,就是可以加東西進去唄。可能是自己太笨,一開始沒怎么注意這意思。竟然往StreamingAssets去實現資源更新(天啦擼)。
?
Application.StreamingAssetsPath,
StreamingAssets目錄必須在Assets根目錄下,該目錄下所有資源也會被打包到游戲里,不同于Resources目錄,該目錄下的資源不會進行壓縮,同樣是只讀不可寫的。
這里的只可讀,不可寫,就是除了出大版本的包(重新下載),這里面的東西永遠不會變。
各平臺StreamingAssets路徑打印:?
Win:E:/myProj/Assets/StreamingAssets?
Mac : /myProj/Assets/StreamingAssets?
Andorid:jar:file:///data/app/com.myCompany.myProj-1/base.apk!/assets?
iOS: /var/containers/Application/E5543D66-83F3-476D-8A8F-49D5332B3763/myProj.app/Data/Raw
Application.PersistentDataPath
?應用程序安裝后才會出現。該目錄獨特之處在于是可讀,可寫的,所以我們一般將下載的AssetBundle存放于此。
各平臺PersistentDataPath路徑打印:?
Win:C:/Users/lodypig/Appdata/LocalLow/myCompany/myProj?
Mac : /Users/lodypig/Library/Application Support/myCompany/myProj?
Andorid:/data/data/com.myCompany.myProj/files?
iOS: /var/mobile/Containers/Data/Appliction/A112252D-6B0E-459Z-9D49-CD3EAC6D47D/Documents
Application.DataPath
應用程序目錄,即Assets目錄。使用Appliction.dataPath訪問。只讀不可寫。
各平臺DataPath路徑:?
Win:E:/myProj/Assets?
Mac : /myProj/Assets/?
Andorid:/data/app/com.myCompany.myProj-1/base.apk!?
iOS: /var/containers/Application/E5543D66-83F3-476D-8A8F-49D5332B3763/myProj.app/Data
綜上,也就是說,要實現資源更新,你只有把資源下載到Application.PersistentDataPath目錄下才可實現資源更新(增加或者替換),其他目錄不可能實現。
?
2.理解上面三種目錄的關系,Unity游戲加載的資源是如何分配的?(彼此的關系)
首先你得有一個資源服務器(FTP為例),因為StreamingAssets目錄是只讀的,我們想要實現熱更新,StreamingAssets
目錄里面的東西一旦第一個版本打出APK的包之后,這里的東西將永遠不會變(只讀)。由于PersistentDataPath目錄是可讀可寫的,
所以游戲下載資源都會下載到這里面。這樣就實現了資源的熱更新。
?
注解:綠色的代表流動,可以不斷可以改變的資源。紅色線代表,讀取persistent目錄沒有的情況下,讀StreamingAssets目錄,所以,是永遠不變的資源。(除非你去重新下載一個apk的包,就不是熱更了)
3.如何加載本地的資源?
?首先優先判斷PersistentDataPath目錄下的資源是否存在,因為服務器上的資源都是下載到這里的,最新的資源通過下載到這里并且覆蓋,這里的資源
能保持跟服務器一致。(雨松之前講的UnityAssetBundle例子就是通過加載服務器上的,那個只是一個小案例,不能每次用哪下載到哪,每次都要下載,
這種方式是很不好用的,就第一次用的時候如果資源與服務器不一致,就下載到本地中,即PersistentDataPath目錄。)
因為每個游戲一開始出大版本的時候,都會附帶大量資源,就是放在StreamingAssets目錄,所以,這里存放大量資源。這樣減少下載的次數。
其實,換一種說法,PersistentDataPath完全是給StreamingAssets的補丁目錄,我是這樣理解的。當然,在項目運用中,都需要優先最先資源判斷。
?4.遇到的那些神神神.....坑?
???(1) 不要以為在PC端可以加載的路徑,安卓也可以用。
我這邊因為涉及到WWW加載,貼出我的。
這里主要是通過www 如何加載PersistentDataPath和StreamingAssets這兩個目錄。
Application.PersistentDataPath:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /// <summary> ??? /// 天吶,一個Per目錄,還兩種方法加載。這真的是最后我找出來最完美的,可以加載的,之前還有N種版本,就不提了,網上有,我是經過實測,Unity5.3.4版本 ??? /// 加載PC上安卓平臺,加載PC上Standalone,加載安卓真機(APK包),這三個,都是可以加載的(WWW加載), ??? /// </summary> ??? public ?static ?string ?PERSISTENT_PATH_DATABASE? //= LGameConfig.LOCAL_URL_PREFIX + Application.persistentDataPath + "/DataBase/"; ??? { ??????? get ??????? { ??????????? #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN ??????????????????? return ???"file:///" + Application.persistentDataPath +? "/Test/" ; ??????????? #else ????????????????????????? return ???"file://" + Application.persistentDataPath +? "/Test/" ; ??????????? #endif ??????? } ??? } |
Application.StreamingAssets:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public ?static ?string ?STREAMING_PATH_DATABASE ???? { ???????? //這樣寫,因為安卓Unity平臺是Application.isMobilePlatform==false, 而宏定義中又? ==UNITY_ANDROID。 ????????? //因為我們項目中是需要同時在PC下安卓平臺和PC下 Standard平臺,哈哈 ???????? get ???????? { ???????????? if ?(!Application.isMobilePlatform) ???????????? { ???????????????? return ?"file://" ?+ Application.dataPath +? "/StreamingAssets" ?+? "/DataBase/" ; ???????????? } ???????????? else ???????????? { ???????????????? return #if UNITY_ANDROID ???????? Application.streamingAssetsPath+?? "/DataBase/" ; #else ?????? "file://" ?+ Application.dataPath +? "/StreamingAssets" ?+? "/DataBase/" ; #endif ???????????? } ???????? } |
這個加載地址,真的是精華,可能自己太笨,就是搞這個WWW加載安卓StreamingAssets目錄,花了大把時間,因為網上,加載方式真的是尼瑪一萬種,要噴一下,這些人,不實際打到APK測一下,我MDGB呀,坑的我好慘。
?
(2)不要以為在PC端可以用的方法,在安卓也可以用。
安卓上跟其他平臺不一樣,安裝后,這些文件實際上是在一個Jar壓縮包里,所以不能直接用讀取文件的函數去讀,而要用WWW方式
讀取的代碼(假設名為"文件.txt")?
(3) 安卓資源路徑加載,下載問題,真的是這次做AssetBundle最大的障礙。
(4)通過FTP和CDN下載資源的時候對應的 后綴是不同的。
? FTP下載 后面用 ? "/" ?,即可。
? CDN下載 后面用 ?"//" ,即可。
(5)不同的加載方式,加載的路徑也是不同的。
具體我就不說了。
(6)記得加 加載文件的后綴名
安卓上跟其他平臺不一樣,安裝后,這些文件實際上是在一個Jar壓縮包里,所以不能直接用讀取文件的函數去讀,而要用WWW方式
1.讀取的代碼(假設名為"文件.txt")?
(7)加載方式,First In PersistentDataPath,Then StreamingAssets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | IEnumerator LoadAnouncementText() ???? { ???????? string ?strUrl = GetTxtPerststentUrl(anouncementText); ???????? WWW www =? new ?WWW(strUrl); ???????? yield ?return ?www; ???????? if ?(www.error ==? null ) ???????? { ???????????? mAnoucementText = ConvertByteToString(www.bytes); ???????? } ???????? else ?if ?(www.isDone) ???????? { ???????????? string ?strPerUrl = GetTxtStreamUrl(anouncementText); ???????????? www =? new ?WWW(strPerUrl); ???????????? yield ?return ?www; ???????????? if ?(www.error ==? null ) ???????????? { ???????????????? mAnoucementText = ConvertByteToString(www.bytes); ???????????? } ???????????? else ?if ?(www.isDone) ???????????? { ???????????????? Debug.LogError( "下載當前表出錯" ??+ www.error.ToString()); ???????????? } ???????? } ???? } string ?GetTxtStreamUrl( string ?name) ???? { ???????? return ?STREAMING_PATH_DATABASE + name +? ".txt" ; ???? } ???? string ?GetTxtPerststentUrl( string ?name) ???? { ???????? return ?PERSISTENT_PATH_DATABASE + name +? ".txt" ; ???? }!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!補充!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!補充:對于上面的路徑問題大家可能有些困惑。貼出最詳細全面的路徑問題,經過測試,完全沒問題(安卓,PC都可以用,實際項目中使用) |
string GetScenePath(string fileName){string path =DataUrl.GetFilePersistentUrl(fileName)+".unity3d";// string path= DataUrl.LOCAL_URL_PREFIX + Application.dataPath + "/StreamingAssets/" + "Scene_Main" + ".unity3d";//讀取Per目錄的時候不需要加prefix,但是讀取Streaming目錄時候需加上prefixbool isPersistentDataPath = System.IO.File.Exists(path);if (!isPersistentDataPath){path = DataUrl.GetFileStreamingUrl(fileName)+ ".unity3d";if (!System.IO.File.Exists(path)){Debug.LogError("Per,Stream目錄 scene bundle都不存在");return null;}}return DataUrl.LOCAL_URL_PREFIX+ path;}DataUrl.cs public static string GetFilePersistentUrl(string path){return Application.persistentDataPath+"/" + path;}public static string GetFileStreamingUrl(string path){return Application.streamingAssetsPath+"/" + path;} #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WINpublic static readonly string LOCAL_URL_PREFIX = "file:///"; #elsepublic static readonly string LOCAL_URL_PREFIX="file://"; #endif
?