赞
踩
对于Unity3d的资源管理已经研究了很久,大概是从大学毕业到现在,依然在不断的探索着,这期间不断的在网上查看各位大神们的讲解,然后自己就研究,也做部分实验,发现其实要很好地管理起来是很容易的,资源更新,加载,卸载对于一款游戏来说是十分重要的,首先我从资源更新说起。
一、资源更新现在有很多的办法,Unity3d提供了很多种资源管理方式。1、你可以将资源存放在工程目录的Resource文件夹下面,这个文件夹下面的资源会随着你导出平台安装包的时候加密到你的安装包里面,unity程序在运行的时候会根据自己的资源加载思路将场景里面用到的资源进行加载,但是这部分资源是不能够及时更新的,也就是说,资源跟新不能考虑这个文件夹;2、unity工程下面还有一个特殊的文件夹,就是StreamingAssets文件夹,这个文件夹会在你导出的时候原封不动的考到安装包里面,在释放到平台上面,注意一点,他是原封不动的,这就需要你采用自己的加密方式,要不会很容易被破解的,这部分资源在各个平台上是可以访问到,安卓手机上面用WWW类进行读取,PC,以及iPhone可以用File类进行读取,很方便。上述两个文件夹是unity提供给我们的,很方便,哈哈。
我自己在研究了那么久之后,决定将大部分用到的,可能需要经常更新的资源存放到了StreamingAssets目录下面,有用到的ngui的图集,以及预设等等,由于iPhone不支持代码更新,我们就在脚本中运用了lua代码,我们采用的是ulua,这都是跟着群里面的大神学习的,首先游戏安装到设备上头一回运行的时候,会将StreamingAssets下面的资源进行复制,释放到平台上面我们自己指定的目录,需要获得读写权限,这个路径Application.streamingAssetsPath就是平台上面的StreamingAssets所在的位置,然后在安卓手机上面访问内置sd卡或sd卡1的路径为/mnt/sdcard,在4.1以后也可用路径/storage/sdcard0这个路径,最后在这个历经下面建立文件夹,存放自己的资源。在iPhone以及PC上面完全可以使用Application.persistentDataPath这个目录进行资源的存放。资源存放好了就可以准备更新了,www可以访问你自己的资源服务器,游戏资源存放得当之后便可以调用new WWW(地址);来进行下载,我们的做法是资源释放到了本地,然后会从服务器上面下载最新的资源配置文件,lua太伟大了,既可以写程序也可以作为配置文件,哈哈,我就将资源的名称以及他们的md5值存放在lua的table里面,然后就是表的遍历了,方法很多,ulua在这方面已经完全可以胜任,支持安卓PC以及iPhone,wp推荐用nlua,nlua我不会,哈哈,怎样打assetbundle类型的资源包网上教程很多,也很详细,如果资源包过大,也可以考虑一下采用压缩,有7z,网上有宣雨松的例子,很好。遍历配置表格,进行md5比对,不同的就进行下载,最终进入游戏。建议是资源尽量分的细一些,这样既方便局部资源的整体替换,同时也有利于团队分工开发,后期的更新维护也会很简单,你可以参考一下别人的安装包,解压看看里面的资源是怎么布置的,看看就好呀,哈哈。共同学习。
二、下面就是资源的加载了,建议大家对Resource类进行适当的利用然后写出一个自己能够方便使用的资源加载类,首先可以从Resource目录下面方便的加载,然后还要很方便的从assetbundle里面进行加载,assetbundle里面的资源你想要用的时候要提前加载,建议做在loading界面里面,这样用户体验会好一些,因为此时用户的耐心是最大的,你一卡一卡的,老板都会揍你,哈哈,这个加载类可以加载assetbundle里面的东西,并将加载的assetbundle交给全局的加载对象管理器,以便进行及时的释放,关于assetbundle的完全释放,网上讲的很多,也很好,我这里面总结一下整体的过程,仅供参考:
1.首先记录下已经加载的assetbundle,以便你好释放;
2.将预设或者图集,图片从里面加载出来,记录;
3.将在第2步里面加载的东西放到场景的某个对象上面,或者直接实例化预设,将这个放到场景里面的这个对象记录下来,因为它上面有对asser的引用;
4.在一个assetbundlle里面所有的用到的资源都加在出来之后,执行语句Resources.UnloadUnusedAssets();会将不用了的asset占用的内存释放出来;
5.场景中通过某一个assetbundle创建的对象或者依附的对象没什么用处的时候,将对象进行Destroy(对象);这个方法,这样对象会从场景里面消失,同时它所引用的资源就没有存在的意义了;
6.将销毁的对象所用的assetbundle执行assetbundle.Unload(false);,这样就会将已经记录的资源包所占用的内存镜像会完全卸载;
7.Resources.UnloadUnusedAssets();卸载没有用到的资源;
8.将记录的加载过的预设,等资源设置为null;
9.Resources.UnloadUnusedAssets();释放资源,
10.调用系统的垃圾回收站清理函数GC.Collect();
通过上面十个步骤,就可以将引用的assetbundle进行彻底的释放,由于在代码里面我与用到了lua脚本,就可能会存在lua的引用,这时需要在第8个步骤里面调用一下lua自身的垃圾回收函数collectgarbage();然后再进行第9步,实验证明是可以的。
我在实际的过程中就是采用的如此的资源更新,加载,以及释放的过程,很方便,没有提到的就是工程里面要有一个对象管理器,就是对象池,需要你对对象进行比较明确的管理,时刻明白场景里面哪些是有用的,哪些是可以释放卸载掉的,这样,unity3d的游戏在平台上才不会内存一直飙高,可能引起的游戏闪退等现象,卡顿也会避免。
最后,大家加油呀!快过年了,程序员还没放假,哈哈
下面是我自己的部分代码,很简单的,只供参考,嘿嘿
--关闭面板(Lua脚本),将场景里面的已将创建的面板进行销毁--GameObjectMgr是我自己写的一个很简单的管理器
function CloseWindow(args)
if(args==nil)then
print('ERROR 变量未正确赋值');
return;
end
local _iswindestory =args['_iswindestory']
local _winname =args['_winname']
local _isassetdestory =args['_isassetdestory']
local _assetname =args['_assetname']
local _ispbdestory =args['_ispbdestory']
local _prefabname =args['_prefabname']
if(GameObjectMgr.IsObjCreated(_winname)==false)then
print("指定窗口不存在,不需要关闭 :",_winname);
return;
end
args =nil;
if(_ispbdestory)then
GameObjectMgr.AdddestoryPerfabList (_prefabname);
end
if(_iswindestory)then
print('销毁窗口');
GameObjectMgr.AdddestoryObjNameList (_winname);
else
print('窗口隐藏');
GameObjectMgr.SetObjActivePority(_winname,false);
end
if(_isassetdestory)then
GameObjectMgr.AdddestoryABList (_assetname);
end
collectgarbage();
--下面将会进行对象销毁,内存释放内存释放
GameObjectMgr.FreeMemory ();
end
改日把我的GameObjectMgr也加进来,供大家参考,周末愉快,下周末我也就放假啦,哈哈哈,开心的等待着
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GameObjectMgr{
public static Dictionary<string,GameObject> loadedPerfabList =null; //存放已经加载的预设资源
public static Dictionary<string,AssetBundle> loadedAssetList =null; //存放AB包
public static Dictionary<string,GameObject> createdObjList =null; //存放创建的对象
public static string[] destoryPerfabList =null; //销毁的预设
public static string[] destoryAssetList =null; //销毁的AB包,unload(false);
public static string[] destoryObjNameList =null; //销毁的对象;
//设置是否显示
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);
}
}
}
}
}
//获得一个已经创建的对象
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;
}
//获得一个已经加载的预设
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;
}
//查看预设是否加载
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;
}
//对象是否已经被创建
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;
}
//添加已经创建
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);
}
//添加已经加载的assetbundle
public static void AddloadedAssetList(string _name, AssetBundle _obj){
if (loadedAssetList == null) {
loadedAssetList = new Dictionary<string, AssetBundle>();
}
if(loadedAssetList.ContainsKey(_name)){
return ;
}
loadedAssetList.Add (_name,_obj);
}
//添加已经加载的预设
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);
}
//添加预设名字
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;
}
}
//添加对象名字
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;
}
}
//清理内存
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 ();
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。