Asset 管理 - FrankNine/franknine.github.io GitHub Wiki
原理
AssetDatabase
原理
YAML & Prefab
原理
- Understanding Unity’s serialization language, YAML
The Asset Bundle dependency calculation considers stale references, which might create unnecessary dependencies between bundles, loading more than required at runtime.
- Technical deep dive into the new Prefab system
AssetBundle
原理
- AssetBundle 與 Resources 指南 (只有翻譯第一章)
- Assets, Resources and AssetBundles (上面的原文)
- [2018 TGDF] 刘伟贤 ─【Unity 議程】AssetBundle 細節解析
- AssetBundles-Browser
- 示範操作 WebExtract 與 binary2text
How do I determine what is in my Scene bundle?
- Unity3D asset bundle 格式简析
- FrankNine/BeyondAssetBundle(嘗試不透過 Unity Editor 製造 AssetBundle,只有 Header 完整)
Workflow
Load
-
AssetBundle.LoadAsset
前一定要先確認所有直接間接依賴到的 AssetBundle 都有讀取,否則會 dereference 失敗Because an Object is loaded when its Instance ID is first dereferenced, and because an Object is assigned a valid Instance ID when its AssetBundle is loaded, the order in which AssetBundles are loaded is not important. Instead, it is important to load all AssetBundles that contain dependencies of an Object before loading the Object itself. Unity will not attempt to automatically load any child AssetBundles when a parent AssetBundle is loaded.
AssetBundle 讀取順序不重要,但是讀出 Asset 瞬間 AssetBundle 依賴要齊全重要
-
Build AssetBundle 會產生
AssetBundleManifest
,可以用AssetBundleManifest.GetAllDependencies
取得某個 AssetBundle 所有需要的依賴(這個會回傳遞迴地依賴關係中依賴
與依賴的依賴
,API 命名有點糟難一眼看出是遞迴的,如果有特殊需求只需要一層的直接依賴
是用AssetBundleManifest.GetDirectDependencies
) -
Scriptable Build Pipeline 產生的 Manifest 跟內建 Build Pipeline 不同,是
CompatibilityAssetBundleManifest
,API 跟AssetBundleManifest
相近但是 Dependency 回傳會包含自己,做 Reference counting 時要特別小心 -
Editor 環境可以用 AssetDatabase.GetAssetBundleDependencies 列出 AssetBundle 依賴
Unload
-
AssetBundle 讀出來的 Asset 不能單獨 Unload,官方提供的建議是將 AssetBundle 切小然後整個
AssetBundle.Unload
We can instead create an AssetBundle for each prefab. These more granular AssetBundles alleviate the problem of large bundles retaining assets in memory that we no longer need.
Tales from the optimization trenches: Saving memory with Addressables
-
但是 AssetBundle 切小也有缺點
-
讀取 AssetBundle 會讀出 SerializedFile 會需要兩個暫存 Buffer,照官方的說法
- Two file read buffers
- A type tree listing every unique type included in the bundle
- A table of contents pointing to the assets
These buffers are 64 KB each on PS4, Switch, and Windows RT, and 7 KB on all other platforms.
Tales from the optimization trenches: Saving memory with Addressables
每個開啟的 AssetBundle 會有 7K * 2 到 64K * 2 的記憶體 Overhead
-
檔案多對檔案系統或是下載也會有負擔,如果下載走 HTTPS 沒辦法 Keep-Alive 重複利用 TCP 連線,重複交握的消耗也會可觀
-
-
Resources.UnloadAsset
對 AssetBundle 讀出來的 Asset 無效 -
Resources.UnloadUnusedAssets
對 AssetBundle 讀出來的 Asset 卻有效,但是不能控制範圍No asset in stuff unloads until the AssetBundle itself is completely unloaded. The exception to this rule is the engine interface Resources.UnloadUnusedAssets. Executing this method in the above scenario causes tree to unload. Because the Addressables system cannot be aware of these events, the profiler graph only reflects the Addressables ref-counts (not exactly what memory holds). Note that if you choose to use Resources.UnloadUnusedAssets, it is a very slow operation, and should only be called on a screen that won't show any hitches (such as a loading screen).
-
有人遇到 Addressable 下
Resources.UnloadUnusedAssets
無法移除已經沒有 Reference 的讀出來的 Asset,Unity 似乎已經修復(需要實驗確認) -
AssetBundle.Unload(false)
有很多奇怪的行為,建議直接AssetBundle.Unload(true)
自己修好會掉東西的地方,不要依賴Unload(false)
造成的殘留效果- Unity 無法保證
Unload(false)
殘留的物件在手機上 App context switch 後持續可用If AssetBundle.Unload(false) is called, live Objects sourced from the unloaded AssetBundle will not be destroyed, but Unity will invalidate the File GUID and Local ID references of their Instance IDs. It will be impossible for Unity to reload these Objects if they are later unloaded from memory and live references to the unloaded Objects remain.
Note: The most common case where Objects are removed from memory at runtime without being unloaded occurs when Unity loses control of its graphics context. This may occur when a mobile app is suspended and the app is forced into the background.
- Unity 無法保證