您好,登錄后才能下訂單哦!
這篇文章主要介紹了Unity AssetBundle如何實現分割與合并,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
Unity AssetBundle 中的資源非常容易被提取,如果想要阻止簡單的提取行為,可以嘗試在打包時將文件分割,在運行時將文件合并。
打包時將文件分割成多個文件,這個可以根據需要指定規則處理。例如可以使用隨機文件名、分割成隨機的份數。
Unity 2017.4 Unity 2018.4 Unity 2019.3 Unity 2020.1 或更高版本新增了一個從流讀取 AssetBundle 的 API,那么可以將多個文件合并為一個文件流供 API 使用。
Unity - Scripting API: AssetBundle.LoadFromStream
雖然通過這個 API 可以自定義 AssetBundle 加載方式,包括加密、多文件讀取、內存中讀取等等。但是有一個致命缺點:使用時占用文件打開數量,而操作系統對文件打開數量是有上限的。
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
具體需要在真機測試,可以嘗試在 Update 中一直打開文件,然后看界面顯示的打開文件數量,到達某一數字后進程會被強制結束。
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class Test : MonoBehaviour
{
List<FileStream> _openFileStreams = new List<FileStream>();
void OnGUI()
{
GUILayout.Label(_openFileStreams.Count.ToString());
}
void Update()
{
_openFileStreams.Add(File.Create(_openFileStreams.Count.ToString()));
}
}
Android上用LoadFromStreamAsync加載報Too many open files – UWA問答:幫助開發者找到更好的答案
以下鏈接中提供了一個可用的 MultiStream 實現,建議參考使用。經測試可以在 Unity 2018.4.12f1 中正確加載 AssetBundle 并讀取其中資源進行實例化顯示到場景中。
Combine Multiple Streams in a Single .NET Framework Stream Object
建議:由于受文件打開數量上限影響,可以考慮只為關鍵資源使用 MultiStream 方式加載。
如果使用 LoadFromFile
API,那么需要提前對文件進行合并,這一步驟可以放在首次啟動時處理。
對文件進行合并的操作可以放在后臺線程中處理,另外可以將文件劃分優先級,只有馬上要用的文件優先處理,處理完成后進入游戲;剩下的文件在后臺繼續處理。
在合并文件時可以使用大小及 MD5 驗證。
MD5 驗證看起來不錯,但是在 Unity 5.6.6f2 + Xcode 11 環境下測試時發現 Debug 版本耗時超長,Release 版本中不受影響。
實際結果是 1800+ 文件共計 180+MB 在 Debug 下需要 150 多秒驗證,懷疑 MD5 代碼中存在數據競爭問題。
考慮到 MD5 驗證意義不大,因為打包時可以保證文件都是正確的,因此這步可以跳過,只做大小驗證。
可以使用 Instruments 工具對耗時進行測試,通過工具可以輕易地看到耗時過長的調用。
大概的使用方法可以參考 Unity 文章:
Optimizing Shader Info Loading, or Look at Yer Data! - Unity Technologies Blog
在合并文件時,要注意盡可能地減少無用操作,例如:
合并的緩存 Buffer 可以在外部預先創建好,然后傳遞給合并方法使用,減少 GC 次數與時間。
增大緩存 Buffer 大小,減少系統調用次數。
減少 IO 操作,包括不限于檢查目錄是否存在、創建目錄、創建文件等等。
使用線程時需要指定線程的優先級為最高,可以為線程多增加一些時間片使用。
使用 StopWatch 處理時,注意 StopWatch 提供的是墻上時間,而不是 CPU 時間,不要被誤導。
減少拆分文件的數量,文件數量的多少直接影響 IO 操作的數量。
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Unity AssetBundle如何實現分割與合并”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。