這篇文章主要介紹了Unity AssetBundle如何實(shí)現(xiàn)分割與合并,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
黃州網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),黃州網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為黃州1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的黃州做網(wǎng)站的公司定做!
Unity AssetBundle 中的資源非常容易被提取,如果想要阻止簡(jiǎn)單的提取行為,可以嘗試在打包時(shí)將文件分割,在運(yùn)行時(shí)將文件合并。
打包時(shí)將文件分割成多個(gè)文件,這個(gè)可以根據(jù)需要指定規(guī)則處理。例如可以使用隨機(jī)文件名、分割成隨機(jī)的份數(shù)。
Unity 2017.4 Unity 2018.4 Unity 2019.3 Unity 2020.1 或更高版本新增了一個(gè)從流讀取 AssetBundle 的 API,那么可以將多個(gè)文件合并為一個(gè)文件流供 API 使用。
Unity - Scripting API: AssetBundle.LoadFromStream
雖然通過這個(gè) API 可以自定義 AssetBundle 加載方式,包括加密、多文件讀取、內(nèi)存中讀取等等。但是有一個(gè)致命缺點(diǎn):使用時(shí)占用文件打開數(shù)量,而操作系統(tǒng)對(duì)文件打開數(shù)量是有上限的。
5.5.4. iOS file handle overuse
Current versions of Unity are not affected by this issue.
In versions prior to Unity 5.3.2p2, Unity would hold an open file handle to an AssetBundle the entire time that the AssetBundle is loaded. This is not a problem on most platforms. However, iOS limits the number of file handles a process may simultaneously have open to 255. If loading an AssetBundle causes this limit to be exceeded, the loading call will fail with a “Too Many Open File Handles” error.
This was a common problem for projects trying to divide their content across many hundreds or thousands of AssetBundles.
Assets, Resources and AssetBundles - Unity Learn
具體需要在真機(jī)測(cè)試,可以嘗試在 Update 中一直打開文件,然后看界面顯示的打開文件數(shù)量,到達(dá)某一數(shù)字后進(jìn)程會(huì)被強(qiáng)制結(jié)束。
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class Test : MonoBehaviour
{
List
_openFileStreams = new List ();
void OnGUI()
{
GUILayout.Label(_openFileStreams.Count.ToString());
}
void Update()
{
_openFileStreams.Add(File.Create(_openFileStreams.Count.ToString()));
}
}
Android上用LoadFromStreamAsync加載報(bào)Too many open files – UWA問答:幫助開發(fā)者找到更好的答案
以下鏈接中提供了一個(gè)可用的 MultiStream 實(shí)現(xiàn),建議參考使用。經(jīng)測(cè)試可以在 Unity 2018.4.12f1 中正確加載 AssetBundle 并讀取其中資源進(jìn)行實(shí)例化顯示到場(chǎng)景中。
Combine Multiple Streams in a Single .NET Framework Stream Object
建議:由于受文件打開數(shù)量上限影響,可以考慮只為關(guān)鍵資源使用 MultiStream 方式加載。
如果使用 LoadFromFile
API,那么需要提前對(duì)文件進(jìn)行合并,這一步驟可以放在首次啟動(dòng)時(shí)處理。
對(duì)文件進(jìn)行合并的操作可以放在后臺(tái)線程中處理,另外可以將文件劃分優(yōu)先級(jí),只有馬上要用的文件優(yōu)先處理,處理完成后進(jìn)入游戲;剩下的文件在后臺(tái)繼續(xù)處理。
在合并文件時(shí)可以使用大小及 MD5 驗(yàn)證。
MD5 驗(yàn)證看起來不錯(cuò),但是在 Unity 5.6.6f2 + Xcode 11 環(huán)境下測(cè)試時(shí)發(fā)現(xiàn) Debug 版本耗時(shí)超長(zhǎng),Release 版本中不受影響。
實(shí)際結(jié)果是 1800+ 文件共計(jì) 180+MB 在 Debug 下需要 150 多秒驗(yàn)證,懷疑 MD5 代碼中存在數(shù)據(jù)競(jìng)爭(zhēng)問題。
考慮到 MD5 驗(yàn)證意義不大,因?yàn)榇虬鼤r(shí)可以保證文件都是正確的,因此這步可以跳過,只做大小驗(yàn)證。
可以使用 Instruments 工具對(duì)耗時(shí)進(jìn)行測(cè)試,通過工具可以輕易地看到耗時(shí)過長(zhǎng)的調(diào)用。
大概的使用方法可以參考 Unity 文章:
Optimizing Shader Info Loading, or Look at Yer Data! - Unity Technologies Blog
在合并文件時(shí),要注意盡可能地減少無用操作,例如:
合并的緩存 Buffer 可以在外部預(yù)先創(chuàng)建好,然后傳遞給合并方法使用,減少 GC 次數(shù)與時(shí)間。
增大緩存 Buffer 大小,減少系統(tǒng)調(diào)用次數(shù)。
減少 IO 操作,包括不限于檢查目錄是否存在、創(chuàng)建目錄、創(chuàng)建文件等等。
使用線程時(shí)需要指定線程的優(yōu)先級(jí)為最高,可以為線程多增加一些時(shí)間片使用。
使用 StopWatch 處理時(shí),注意 StopWatch 提供的是墻上時(shí)間,而不是 CPU 時(shí)間,不要被誤導(dǎo)。
減少拆分文件的數(shù)量,文件數(shù)量的多少直接影響 IO 操作的數(shù)量。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Unity AssetBundle如何實(shí)現(xiàn)分割與合并”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!