資源描述:
《unity動態(tài)加載模型》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在應用文檔-天天文庫。
1、模型、視頻、音頻等資源動態(tài)加載,卸載Unity里有兩種動態(tài)加載機制:一是Resources.Load,一是通過AssetBundle,其實兩者本質(zhì)上我理解沒有什么區(qū)別。Resources.Load就是從一個缺省打進程序包里的AssetBundle里加載資源,而一般AssetBundle文件需要你自己創(chuàng)建,運行時動態(tài)加載,可以指定路徑和來源的。其實場景里所有靜態(tài)的對象也有這么一個加載過程,只是Unity后臺替你自動完成了。詳細說一下細節(jié)概念:AssetBundle運行時加載:來自文件就用CreateFromF
2、ile(注意這種方法只能用于standalone程序)這是最快的加載方法也可以來自Memory,用CreateFromMemory(byte[]),這個byte[]可以來自文件讀取的緩沖,www的下載或者其他可能的方式。其實WWW的assetBundle就是內(nèi)部數(shù)據(jù)讀取完后自動創(chuàng)建了一個assetBundle而已Create完以后,等于把硬盤或者網(wǎng)絡的一個文件讀到內(nèi)存一個區(qū)域,這時候只是個AssetBundle數(shù)據(jù)塊,并沒有Object的概念。Assets加載:用AssetBundle.Load(同Reso
3、urces.Load)這才會從AssetBundle的內(nèi)存鏡像里讀取并創(chuàng)建一個Asset對象,創(chuàng)建Asset對象同時也會分配一塊內(nèi)存用于存放(反序列化)異步讀取用AssetBundle.LoadAsync也可以一次讀取多個用AssetBundle.LoadAllAssetBundle的釋放:AssetBundle.Unload(flase)是釋放AssetBundle文件的內(nèi)存鏡像,不包含Load創(chuàng)建的Asset內(nèi)存對象。AssetBundle.Unload(true)是釋放那個AssetBundle文件內(nèi)
4、存鏡像和并銷毀所有用Load創(chuàng)建的Asset內(nèi)存對象。一個Prefab從assetBundle里Load出來里面可能包括:Gameobjecttransformmeshtexturematerialshader和各種其他component你Instaniate一個Prefab,是一個Clone+引用結(jié)合的過程,GameObject和transform等是Clone是新生成的,其他mesh/texture/material/shader等這些是引用的關(guān)系,引用對象的不會被復制,只是一個簡單的指針指向已經(jīng)Loa
5、d的Asset對象(mesh是引用還是Clone不清楚貌似是都有)。這種含糊的引用加克隆的混合,大概是搞糊涂大多數(shù)人的主要原因。你可以再Instaniate一個同樣的Prefab,還是這套mesh/texture/material/shader...,這時候會有新的GameObject等,但是不會創(chuàng)建新的引用對象比如Texture.所以你Load出來的Assets其實就是個數(shù)據(jù)源,用于生成新對象或者被引用,生成的過程可能是復制(clone)也可能是引用(指針)當你Destroy一個實例時,只是釋放那些Clo
6、ne對象,并不會釋放引用對象和Clone的數(shù)據(jù)源對象,Destroy并不知道是否還有別的object在引用那些對象。等到?jīng)]有任何游戲場景物體在用這些Assets以后,這些assets就成了沒有引用的游離數(shù)據(jù)塊了,是UnusedAssets了,這時候就可以通過Resources.UnloadUnusedAssets來釋放,Destroy不能完成這個任務,AssetBundle.Unload(false)也不行,AssetBundle.Unload(true)可以但不安全,除非你很清楚沒有任何對象在用這些Ass
7、ets了。雖然都叫Asset,但克隆的和引用的是完全不一樣的,這點被Unity的暗黑技術(shù)細節(jié)掩蓋了,需要自己去理解。關(guān)于內(nèi)存管理按照傳統(tǒng)的編程思維,最好的方法是:自己維護所有對象,用一個Queue來保存所有object,不用時該Destory的,該Unload的自己處理。但這樣在C#.net框架底下有點沒必要,而且很麻煩。穩(wěn)妥起見你可以這樣管理創(chuàng)建時:先建立一個AssetBundle,無論是從www還是文件還是memory用AssetBundle.load加載需要的asset加載完后立即AssetBundl
8、e.Unload(false),釋放AssetBundle文件本身的內(nèi)存鏡像,但不銷毀加載的Asset對象。(這樣你不用保存AssetBundle的引用并且可以立即釋放一部分內(nèi)存)?釋放時:如果有Instantiate的對象,用Destroy進行銷毀在合適的地方調(diào)用Resources.UnloadUnusedAssets,釋放已經(jīng)沒有引用的Asset.如果需要立即釋放內(nèi)存加上GC.Collect(),否則內(nèi)存未必