其實這並沒什么技術難點,也不是完美的熱更新方案,只能說是退而求其次的一個方法。
起因主要是因為公司幾個U3D項目在立項之初都沒有能做好熱更新的規化,導致現在要去做U3D的熱更新非常難,並且項目已處於中后期,大部分的方案不管是用反射,還是用Lua,或是jsbinding,都需要把項目大部分代碼結構推倒重來,這是非常不現實的。於是退而求其次,選擇還是直接用最小APK來更新游戲。
也許很多人也是這么做的,但未見人分享,寫這篇Blog的目的主要是在網上很難搜到相關的整理,並且大部分游戲制作者僅僅是對開發游戲和用Unity會比較熟悉,對Andriod和iOS並不熟悉,所以有些方法可能想到了,但如果沒有人去驗證過,總還是不放心的,於是就打算記錄下來分享給大家。
方案重點就是:用戶在第一次安裝游戲的時候可以用完整的APK包來進行安裝,在之后如果存在邏輯代碼需要更新時,僅需幫用戶下載7MB左右的一個最小APK來把游戲覆蓋安裝即可。(雖然這個7MB左右還是比較大)
我想強調一下,這種方式是100%可行的,只適合於安卓,已驗證,並且正在使用,沒有更好的方案前會一直用,有好的更新方案后也會在Blog更新,並且也希望大家能分享。
U3D的資源更新的方式有兩種,這兩種方式能保證游戲的資源更新,具體就不詳細說明了:
1. WWW.LoadFromCacheOrDownload,這種方式主要是只支持AssetBundle,所以你需要將所有文件打包成AssetBundle。
2. WWW之后用File來寫到磁盤,這種方式就得自己來控制版本了。
用最小APK來更新游戲邏輯的具體步驟:
第一步:拷貝APK安裝路徑Application.dataPath的asset目錄文件到可讀寫目錄Application.persistentDataPath
在第一次初始化游戲的時候,需要通過WWW.LoadFromCacheOrDownload將所有游戲里用到的資源加載一次(或者WWW+File,在打包APK時將所有asset做成一個zip包,第一次啟動游戲時解壓到Application.persistentDataPath),讓他們放進緩存(這個過程視游戲安裝包大小而定,當然,你也可以在其它你覺得合適的時候才做這件事件)。
第二步:制作最小安裝包
將工程中StreamingAssets這個目錄下的文件全部清空,然后再用Unity打包一個APK,這個APK大概有7MB左右。
第三步:更新邏輯
將你制作的最小的APK放到網站服務器上,通過WWW.bytes來下載,然后用FileStream來寫到到Application.persistentDataPath。
第四步:調用Andriod的系統API,來執行APK的安裝(怎么調用可以去百度搜“Unity Andriod交互”,"Andriod 安裝APK 代碼")。
這個安裝會覆蓋掉之前安裝的APK,由於這個APK里asset目錄是空的,所以覆蓋之后也就沒有asset了,這也是為什么要做第一步的原因。另外,這個Application.persistentDataPath+filename 在Java端調用的時候,需要在路徑最前面添加"file://"。
這里強調一下,重新安裝APK后,Application.persistentDataPath和WWW.LoadFromCacheOrDownload緩存的文件,是不會被覆蓋的,所以請放心覆蓋原來的APK。
雖然說這種方法的確不怎么人性化,每次要用戶下載的更新包最小也是7MB+,另外每次還要彈出那個Andriod上安裝APK的對話框,但是,誰叫我們在最初用U3D的時候不好好規划下熱更新的問題呢。
同時也在此呼吁Unity3D官方能給出熱更新方案,至少給出Andriod的邏輯熱更方案,明明只需要把*.so的加載路徑改為可配置,大家就可以方便地實現邏輯的熱更新,但確沒有提供這樣的方法。我只想說,Unreal4都開源了,Unity3D還拿什么競爭。