Unity3d资源管理模块
對(duì)于Unity3d的資源管理已經(jīng)研究了很久,大概是從大學(xué)畢業(yè)到現(xiàn)在,依然在不斷的探索著,這期間不斷的在網(wǎng)上查看各位大神們的講解,然后自己就研究,也做部分實(shí)驗(yàn),發(fā)現(xiàn)其實(shí)要很好地管理起來(lái)是很容易的,資源更新,加載,卸載對(duì)于一款游戲來(lái)說(shuō)是十分重要的,首先我從資源更新說(shuō)起。
一、資源更新現(xiàn)在有很多的辦法,Unity3d提供了很多種資源管理方式。1、你可以將資源存放在工程目錄的Resource文件夾下面,這個(gè)文件夾下面的資源會(huì)隨著你導(dǎo)出平臺(tái)安裝包的時(shí)候加密到你的安裝包里面,unity程序在運(yùn)行的時(shí)候會(huì)根據(jù)自己的資源加載思路將場(chǎng)景里面用到的資源進(jìn)行加載,但是這部分資源是不能夠及時(shí)更新的,也就是說(shuō),資源跟新不能考慮這個(gè)文件夾;2、unity工程下面還有一個(gè)特殊的文件夾,就是StreamingAssets文件夾,這個(gè)文件夾會(huì)在你導(dǎo)出的時(shí)候原封不動(dòng)的考到安裝包里面,在釋放到平臺(tái)上面,注意一點(diǎn),他是原封不動(dòng)的,這就需要你采用自己的加密方式,要不會(huì)很容易被破解的,這部分資源在各個(gè)平臺(tái)上是可以訪問(wèn)到,安卓手機(jī)上面用WWW類進(jìn)行讀取,PC,以及iPhone可以用File類進(jìn)行讀取,很方便。上述兩個(gè)文件夾是unity提供給我們的,很方便,哈哈。
我自己在研究了那么久之后,決定將大部分用到的,可能需要經(jīng)常更新的資源存放到了StreamingAssets目錄下面,有用到的ngui的圖集,以及預(yù)設(shè)等等,由于iPhone不支持代碼更新,我們就在腳本中運(yùn)用了lua代碼,我們采用的是ulua,這都是跟著群里面的大神學(xué)習(xí)的,首先游戲安裝到設(shè)備上頭一回運(yùn)行的時(shí)候,會(huì)將StreamingAssets下面的資源進(jìn)行復(fù)制,釋放到平臺(tái)上面我們自己指定的目錄,需要獲得讀寫權(quán)限,這個(gè)路徑Application.streamingAssetsPath就是平臺(tái)上面的StreamingAssets所在的位置,然后在安卓手機(jī)上面訪問(wèn)內(nèi)置sd卡或sd卡1的路徑為/mnt/sdcard,在4.1以后也可用路徑/storage/sdcard0這個(gè)路徑,最后在這個(gè)歷經(jīng)下面建立文件夾,存放自己的資源。在iPhone以及PC上面完全可以使用Application.persistentDataPath這個(gè)目錄進(jìn)行資源的存放。資源存放好了就可以準(zhǔn)備更新了,www可以訪問(wèn)你自己的資源服務(wù)器,游戲資源存放得當(dāng)之后便可以調(diào)用new WWW(地址);來(lái)進(jìn)行下載,我們的做法是資源釋放到了本地,然后會(huì)從服務(wù)器上面下載最新的資源配置文件,lua太偉大了,既可以寫程序也可以作為配置文件,哈哈,我就將資源的名稱以及他們的md5值存放在lua的table里面,然后就是表的遍歷了,方法很多,ulua在這方面已經(jīng)完全可以勝任,支持安卓PC以及iPhone,wp推薦用nlua,nlua我不會(huì),哈哈,怎樣打assetbundle類型的資源包網(wǎng)上教程很多,也很詳細(xì),如果資源包過(guò)大,也可以考慮一下采用壓縮,有7z,網(wǎng)上有宣雨松的例子,很好。遍歷配置表格,進(jìn)行md5比對(duì),不同的就進(jìn)行下載,最終進(jìn)入游戲。建議是資源盡量分的細(xì)一些,這樣既方便局部資源的整體替換,同時(shí)也有利于團(tuán)隊(duì)分工開(kāi)發(fā),后期的更新維護(hù)也會(huì)很簡(jiǎn)單,你可以參考一下別人的安裝包,解壓看看里面的資源是怎么布置的,看看就好呀,哈哈。共同學(xué)習(xí)。
二、下面就是資源的加載了,建議大家對(duì)Resource類進(jìn)行適當(dāng)?shù)睦萌缓髮懗鲆粋€(gè)自己能夠方便使用的資源加載類,首先可以從Resource目錄下面方便的加載,然后還要很方便的從assetbundle里面進(jìn)行加載,assetbundle里面的資源你想要用的時(shí)候要提前加載,建議做在loading界面里面,這樣用戶體驗(yàn)會(huì)好一些,因?yàn)榇藭r(shí)用戶的耐心是最大的,你一卡一卡的,老板都會(huì)揍你,哈哈,這個(gè)加載類可以加載assetbundle里面的東西,并將加載的assetbundle交給全局的加載對(duì)象管理器,以便進(jìn)行及時(shí)的釋放,關(guān)于assetbundle的完全釋放,網(wǎng)上講的很多,也很好,我這里面總結(jié)一下整體的過(guò)程,僅供參考:
1.首先記錄下已經(jīng)加載的assetbundle,以便你好釋放;
2.將預(yù)設(shè)或者圖集,圖片從里面加載出來(lái),記錄;
3.將在第2步里面加載的東西放到場(chǎng)景的某個(gè)對(duì)象上面,或者直接實(shí)例化預(yù)設(shè),將這個(gè)放到場(chǎng)景里面的這個(gè)對(duì)象記錄下來(lái),因?yàn)樗厦嬗袑?duì)asser的引用;
4.在一個(gè)assetbundlle里面所有的用到的資源都加在出來(lái)之后,執(zhí)行語(yǔ)句Resources.UnloadUnusedAssets();會(huì)將不用了的asset占用的內(nèi)存釋放出來(lái);
5.場(chǎng)景中通過(guò)某一個(gè)assetbundle創(chuàng)建的對(duì)象或者依附的對(duì)象沒(méi)什么用處的時(shí)候,將對(duì)象進(jìn)行Destroy(對(duì)象);這個(gè)方法,這樣對(duì)象會(huì)從場(chǎng)景里面消失,同時(shí)它所引用的資源就沒(méi)有存在的意義了;
6.將銷毀的對(duì)象所用的assetbundle執(zhí)行assetbundle.Unload(false);,這樣就會(huì)將已經(jīng)記錄的資源包所占用的內(nèi)存鏡像會(huì)完全卸載;
7.Resources.UnloadUnusedAssets();卸載沒(méi)有用到的資源;
8.將記錄的加載過(guò)的預(yù)設(shè),等資源設(shè)置為null;
9.Resources.UnloadUnusedAssets();釋放資源,
10.調(diào)用系統(tǒng)的垃圾回收站清理函數(shù)GC.Collect();
通過(guò)上面十個(gè)步驟,就可以將引用的assetbundle進(jìn)行徹底的釋放,由于在代碼里面我與用到了lua腳本,就可能會(huì)存在lua的引用,這時(shí)需要在第8個(gè)步驟里面調(diào)用一下lua自身的垃圾回收函數(shù)collectgarbage();然后再進(jìn)行第9步,實(shí)驗(yàn)證明是可以的。
我在實(shí)際的過(guò)程中就是采用的如此的資源更新,加載,以及釋放的過(guò)程,很方便,沒(méi)有提到的就是工程里面要有一個(gè)對(duì)象管理器,就是對(duì)象池,需要你對(duì)對(duì)象進(jìn)行比較明確的管理,時(shí)刻明白場(chǎng)景里面哪些是有用的,哪些是可以釋放卸載掉的,這樣,unity3d的游戲在平臺(tái)上才不會(huì)內(nèi)存一直飆高,可能引起的游戲閃退等現(xiàn)象,卡頓也會(huì)避免。
最后,大家加油呀!快過(guò)年了,程序員還沒(méi)放假,哈哈
下面是我自己的部分代碼,很簡(jiǎn)單的,只供參考,嘿嘿
改日把我的GameObjectMgr也加進(jìn)來(lái),供大家參考,周末愉快,下周末我也就放假啦,哈哈哈,開(kāi)心的等待著
using UnityEngine; using System.Collections; using System.Collections.Generic;public class GameObjectMgr{public static Dictionary<string,GameObject> loadedPerfabList =null; //存放已經(jīng)加載的預(yù)設(shè)資源public static Dictionary<string,AssetBundle> loadedAssetList =null; //存放AB包public static Dictionary<string,GameObject> createdObjList =null; //存放創(chuàng)建的對(duì)象public static string[] destoryPerfabList =null; //銷毀的預(yù)設(shè)public static string[] destoryAssetList =null; //銷毀的AB包,unload(false);public static string[] destoryObjNameList =null; //銷毀的對(duì)象;//設(shè)置是否顯示public static void SetObjActivePority(string _name,bool _active){if (createdObjList == null) {} else {foreach(string key in createdObjList.Keys){if(key==_name){if(createdObjList[key]!=null){createdObjList[key].SetActive(_active);}else{createdObjList.Remove(_name);}} } }}//獲得一個(gè)已經(jīng)創(chuàng)建的對(duì)象public static GameObject GetGameObjectByName(string _name){ if (createdObjList == null) {return null;} else {foreach(string key in createdObjList.Keys){if(key==_name){if(createdObjList[key]!=null){return createdObjList[key];}else{createdObjList.Remove(_name);return null;}} } }return null;}//獲得一個(gè)已經(jīng)加載的預(yù)設(shè)public static GameObject GetPrefabByName(string _name){ if (loadedPerfabList == null) {return null;} else {foreach(string key in loadedPerfabList.Keys){if(key==_name){if(loadedPerfabList[key]!=null){return loadedPerfabList[key];}else{loadedPerfabList.Remove(_name);return null;}} } }return null;}//查看預(yù)設(shè)是否加載public static bool IsPerfabLoaded(string _name){if (loadedPerfabList == null) {return false;} else {foreach(string key in loadedPerfabList.Keys){if(key==_name){if(loadedPerfabList[key]!=null)return true;else{loadedPerfabList.Remove(_name);return false;}} } }return false;}//對(duì)象是否已經(jīng)被創(chuàng)建public static bool IsObjCreated(string _name){if (createdObjList == null) {return false;} else {foreach(string key in createdObjList.Keys){if(key==_name){if(createdObjList[key]!=null){return true;}else{createdObjList.Remove(_name);return false;}} } }return false;}//添加已經(jīng)創(chuàng)建public static void AddCreatedObjList(string _name, GameObject _obj){if (createdObjList == null) {createdObjList = new Dictionary<string, GameObject>(); }if(createdObjList.ContainsKey(_name)){return ;}createdObjList.Add (_name,_obj);}//添加已經(jīng)加載的assetbundlepublic static void AddloadedAssetList(string _name, AssetBundle _obj){if (loadedAssetList == null) {loadedAssetList = new Dictionary<string, AssetBundle>(); }if(loadedAssetList.ContainsKey(_name)){return ;}loadedAssetList.Add (_name,_obj);}//添加已經(jīng)加載的預(yù)設(shè)public static void AddloadedPerfabList(string _name, GameObject _obj){if (loadedPerfabList == null) {loadedPerfabList = new Dictionary<string, GameObject>(); }if(loadedPerfabList.ContainsKey(_name)){return ;}loadedPerfabList.Add (_name,_obj);}//添加預(yù)設(shè)名字public static void AdddestoryPerfabList(string _name){if (destoryPerfabList == null) {destoryPerfabList = new string[1];destoryPerfabList[0] = _name;return;} else {int j = destoryPerfabList.Length;destoryPerfabList[j] = _name;return;}}//添加對(duì)象名字public static void AdddestoryObjNameList(string _name){if (destoryObjNameList == null) {destoryObjNameList = new string[1];destoryObjNameList[0] = _name;return;} else {int i=destoryObjNameList.Length;destoryObjNameList[i] = _name;return;}}//添加assetbundle名字public static void AdddestoryABList(string _name){if (destoryAssetList == null) {destoryAssetList = new string[1];destoryAssetList[0] =_name;return;} else {int j = destoryAssetList.Length;destoryAssetList[j] = _name;return;}}//清理內(nèi)存public static void FreeMemory(){if (destoryObjNameList == null&&destoryPerfabList.Length== null&&destoryAssetList== null) {Debug.Log("不需要釋放資源"); return;}int i = 0;if (destoryObjNameList != null) {i = destoryObjNameList.Length;for(int j = i-1;j>=0;j--){if(destoryObjNameList[j]!=null)if(createdObjList.ContainsKey(destoryObjNameList[j])){GameObject obj=createdObjList[destoryObjNameList[j]];createdObjList.Remove(destoryObjNameList[j]);GameObject.Destroy(obj);}destoryObjNameList[j]=null;} }destoryObjNameList = null;if (destoryPerfabList != null) {i = destoryPerfabList.Length;for(int j = i-1;j>=0;j--){if(destoryPerfabList[j]!=null)if(loadedPerfabList.ContainsKey(destoryPerfabList[j])){loadedPerfabList[destoryPerfabList[j]]=null;loadedPerfabList.Remove(destoryPerfabList[j]);}destoryPerfabList[j]=null;} }destoryPerfabList = null;if (destoryAssetList == null || destoryAssetList.Length == 0) {} else {i = destoryAssetList.Length;for(int j =i-1;j>=0;j--){if(destoryAssetList[j]!=null)if(loadedAssetList.ContainsKey(destoryAssetList[j]))AssetBundle asset = loadedAssetList[destoryAssetList[j]];loadedAssetList.Remove(destoryAssetList[j]);asset.Unload(false);}destoryAssetList[j]=null;}}destoryAssetList = null;Resources.UnloadUnusedAssets ();System.GC.Collect ();} }總結(jié)
以上是生活随笔為你收集整理的Unity3d资源管理模块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 10 个最佳 GIS 软件应用程序
- 下一篇: CAD中的形及线型