Unity Assets 资源加载与优化干货笔记(一)

干货预警!!!

Unity Assets 资源加载与优化笔记

    • 一、资源加载与使用
    • 二、版本管理
    • 三、Unity打包资源
    • 四、资源卸载
    • 五、关于AssetBundle
    • 六、游戏对象
    • 七、特殊文件夹
    • 八、推荐资源加载策略
    • 九、查找资源引用关系

一、资源加载与使用

1】所有Assets目录下的资源都可以被AssetDatabase类访问并加载。
资源分为两类:一类时引擎可识别的资源,prefab,声音,视频,动画,UI等;第二类是第三方导入的,通过第三方工具解析成引擎可识别的资源。
一些常用操作的API

AssetDatabase.LoadAssetAtPath("相对于Assets的相对路径");
AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Cube.prefab");
AssetDatabase.DeleteAsset(path);  //删除某个资源文件
//加载自定义的资源
AnimInfoList rList = AssetDatabase.LoadAssetAtPath(animInfoFilePath, typeof(AnimInfoList)) as AnimInfoList;
rList = GameObject.Instantiate(rList);  //实例化资源
AssetDatabase.CreateAsset(rList, animInfoFilePath);  //创建资源
AssetDatabase.SaveAssets();  //保存资源
AssetDatabase.Refresh(); //刷新Project视图目录

//获取所有依赖
string[] deps = AssetDatabase.GetDependencies(uiFilePath)
//获取子文件夹
string[] subFolders = AssetDatabase.GetSubFolders(searchPath_)
//获取资源路径
AssetDatabase.GetAssetPath(obj)

2】编辑模式下可以这样实例化prefab(FBX是一种特殊的引用关系的资源,也可以这样实例化)

//这样实例化会保持原有的引用关系,并非克隆一份新的
Gameobject go = PrefabUtility.InstantiatePrefab(prefab) as Gameobject; 
//设置父物体的时候,如果传入false,则表示不被父坐标影响,会归zero。
go.transform.SetParent(Selection.activeTransform, false)  

3】编辑模式下判断当前选择的是否是prefab

Object prefab = PrefabUtility.GetPrefabParent(Selection.activeGameObject);
if(prefab)
{
     
    //是
}

对prefab的相关操作都在PrefabUtility类中。

4】编辑模式卸载资源

// 第二个参数true:卸载游戏对象引用的资源,默认是false
GameObject.DestroyImmediate(Object obj, bool unloadAssets)

5】Unity为了避免IO阻塞,当调用GameObject.Destroy()和GameObject.DestroyImmediate()的时候,只卸载它的对象,它身上的引用的贴图和mesh还在内存中。
为了解决这个问题,unity提供了Resources.UnloadUnusedAssets() 方法去卸载没有引用的资源。
编辑模式使用EditorUtility.UnloadUnusedAssetsImmediate().
6】GameObject.Destroy()删除对象是等1帧后再删除,避免当前帧后面还在使用,建议使用它进行删除。

二、版本管理

1】unity工程只需要将Assets和ProjectSetting文件夹下的所有文件以及meta文件上传管理就行。
2】.meta文件是记录游戏资源在引擎中的一些设置信息,资源最终呈现是根据设置进行优化的。
最重要的就是每个meta里的guid了。用来关联资源与游戏对象的引用的。
例如场景中一个模型用到了一个贴图,则模型对应的prefab的meta文件会引用贴图的guid。如果模型不是prefab,则场景的meta文件会记录。
3】meta文件一定要上传,不然别人更新到这个资源的时候,无法用它本来的设置。
4】程序跟美术维护版本方法
4.1】方法1、程序的工程下,添加一个美术的svn外链,版本同步。
4.2】方法2、美术只在主分支提交,程序需要从主分支合并。
4.3】美术上传的资源要通过程序工具整合后在resources目录下供后续出包使用,不能直接用。

三、Unity打包资源

1】Unity会将被引用的资源打进包内,如果某个scene被添加到scenes in build中的话,scene里面所有引用到的资源都会打进包内。
2】Resources目录下文件无论是否有被引用,unity都会自动将他们合并在一起,压缩后打进包内。在代码中动态读取这些资源并加载。
特别注意:resources目录下的资源尽量不要直接引用在场景中,否则这个资源会被场景和resources打成两份进包。
3】unity打包时会将streamingAssets(无压缩)以及Resources目录下(压缩)打进包内。

四、资源卸载

1】先GC还是先UnloadUnusedAssets() ,当然最好是执行两遍。
2】个人理解,有一些临时对象引用着资源,所以如果先卸载资源,会卸载不掉,如果先GC会将临时对象GC掉,然后卸载资源才更有效。
那有人说要先卸载没用的资源,才能更好的GC掉没有引用的变量。 那这些资源都能被卸载了,就说明他们是没有被某些变量引用着的,你卸载不卸载跟能不能更好的GC没关系。人家本身就没有被变量引用,就算你不卸载资源,该GC还是被GC。 个人偏向先GC再卸载。有些项目是先卸载资源再GC,这个看情况吧,影响有,但不大。最好还是执行两遍,或者合适的时机主动处理。

五、关于AssetBundle

1】将指定一些资源构建成AssetBundle文件,以便下载更新。
2】资源的右下角选择abName以及资源的后缀名(可默认)
3】不管你生成到哪个目录下,最后是要输出到streamingAssets目录下的。别的目录无法读取。
4】会被多引用的资源一定要设置ab,否则会被打成多份。
5】打ab的压缩方式有3种,高压缩慢加载,中压缩中加载,不压缩高加载。项目中推荐使用这种:ChunkBaseConpression
6】加载的流程:
6.1】加载AssetBundleManifest获取ab的依赖关系

manifest = manifestAssetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

6.2】加载依赖的ab

LoadFromFile(path);

6.3】加载本身的ab
6.4】从ab中加载资源

assetbundle.LoadAsset<GameObject>("cube");

6.5】实例化资源。
7】下载的ab资源会首先下载到Application.persistentDataPath(持久化数据路径,玩家就不会退出游戏就没了,跟持久化数据的保存一样)
8】如果场景是从ab中加载的,那么场景是不需要添加到scenes in build中的,这样会减少包体大小。

SceneManager.LoadScene("scene-ab");

9】图解ab加载及内存占用(重要)
Unity Assets 资源加载与优化干货笔记(一)_第1张图片
图片来源

六、游戏对象

1】安全的删除所有子物体,建议使用GameObject.Destroy()并且从后往前删。最好不要while循环一直删除第0个元素。
2】获取游戏对象

GameObject g1 = GameObject.Find("");  //根据scene中完整路径获取游戏对象
GameObject g2 = g1.transform.Find("");  //根据相对路径获取某游戏对象下的子对象

3】获取组件

GetComponentInChildren<>();  //包括自身  InParent同样
GameObject.FindObjectsOfType<Camera>(); //获取场景内所有camera组件

七、特殊文件夹

1】EditorDefaultResorces:编辑模式下的资源可以放这里
2】Plugins:此文件夹下的代码会优先编译成dll文件
3】StandardAssets:导入Unity标准的package文件夹,这里的脚本执行顺序会设置的靠前
4】~ 隐藏文件夹不进入包体 比如将Resources文件夹改成Resources~ 则不会打进包体,

八、推荐资源加载策略

1】从application.persistentDataPath目录下查找读写目录下是否有我要加载的ab
2】如果1没找到,接着去Application.steamingAssetsPath目录下查找本地是否有
3】如果2没找到,接着去resources目录下加载
上述策略使用的同时需要考虑ab的卸载时机

资源更新:
1】将cdn上的资源下载并保存在Application.persistentDataPath目录中,然后按上面的加载顺序加载。 自己要维护一个列表,判断是否需要更新
2】AssetBundle不能信任MD5的,要使用Unity提供的散列值来确保一致性

AssetBundleManifest.GetAssetBundleHash()

所以在构建ab的时候要设置 BuildAssetBundleOptions.DeterministicAssetBundle参数才行

九、查找资源引用关系

1】Unity提供了查找这个资源在当前场景中什么地方引用
Find References in Scene
2】Unity提供了查找这个资源应用了哪些资源
Select Dependencies
但是没有提供这个资源被哪些资源引用,这个百度很多,自己copy一份到自己工程就行。

你可能感兴趣的:(Unity,性能优化,Unity,Asset,Bundle,assets)