本文分享Unity中的资源管理-资源类型和基本使用
真不容易, 经过几篇文章的铺垫, 我们终于进入正题了.
今天继续给大家聊聊资源管理中的基础知识: 资源的类型和基本的使用.
Unity中的资源类型
这一部分在官方文档里介绍的很清楚, 有兴趣的同学可以自行跳转:
如果不愿意看官网, 以下我们简单做一下梳理和总结. 大家也可以有个大致的印象.
Unity常见的资源类型有:
- Texture(纹理), Sprite(精灵): BMP、TIF、TGA、JPG、PNG 和 PSD
- Sound(音效): Mp3, Wav, OGG, AIFF
- Fbx(模型): Dae、3ds、Dxf、Obj、Max
- Mesh(网格)
- Animation(动画), Animator(动画控制器)
- Font(字体): TTF, BMFont, Fnt
- Shader(着色器)
- Meterial(材质)
- Prefab(预制)
其中大部分不需要实例化, 加载完成即可使用.
各种资源导入Unity之后, Unity会对其进行一些配置, 比如音效和图片在不同平台下的压缩方式, 图片是按照纹理方式还是按照精灵方式使用等.
Unity不会使用资源的原始版本, 而是对每个资源进行配置, 即所谓AssetImporter
, 并生成对应的.meta
文件用于描述, 最后在Library
中生成最终在Unity使用的资源, 在发布时和运行时, 使用的是Unity生成的版本.
我们可以重写各种AssetImporter
, 从而在各种资源导入时做自定义的逻辑, 比如导入图片时, 默认将其按照文件夹制作为图集(Atlas).
下面是一张图片的导入设置:
本文分享
第一个红圈代表这个图片的类型, 是纹理还是精灵等.
第二个红圈是在各个平台下的压缩设置.
下面是其对应的.meta
文件内容:
.meta
文件描述了图片信息和使用方式, 比如上面包含了文件的唯一ID, 导入设置信息等. 这里只截取部分, 更多的内容有机会我们单独再讨论.
本章节只是对资源类型进行简单的举例和梳理总结, 大家目前只需要知道:
- Unity中支持各种类型的资源
- 每个资源在导入后都会生成一个对应的配置文件
.meta
- Unity不直接使用资源的原始文件, 而是根据导入配置重新生成Unity中统一使用的资源
- 可以重写某种类型资源的导入设置, 添加自定义部分
- 大部分资源加载后即可直接使用, 少部分需要实例化后使用
资源加载和卸载的几种方式
在Unity中, 有几种资源的加载方式, 各有各的适用范围. 主要涉及到几个类的使用:
Resources
AssetBundle
AssetDatabase
最简单的加载卸载方式: Resources
将资源放在Assets/Resources
目录(可以自行创建)后, 就可以直接使用Resources.Load("path")
加载资源并使用, 且不需要文件扩展名.
使用Resources.UnloadAsset(obj)
卸载资源, 需要传入资源对象.
使用Resources.UnloadUnusedAssets()
卸载资源所有不再使用的资源.
这种方式最为简单, 但是该目录下的资源大小不能超过2G, 如果游戏比较小, 就可以采用这种方式, 可以极大减小资源管理的复杂度.
因为这种方式最简单, 也最快, 所以可以结合其它方式使用, 比如将基本不会变的或者游戏启动时必要的少量资源使用这个方式,然后经常变动的资源使用Ab, 最后通过热更新替换资源.
这种方式提供同步和异步加载接口.
大型项目使用最多的加载卸载方式: AssetBundle
小型项目使用Resources.Load
已经足够, 但是这只是一种很粗粒度的资源管理, 在大型项目中却显得不是那么好用.
在大型项目中, 一般会使用热更的方式更新资源, 而且资源之间的依赖和管理需求更加细致, 我们需要对资源进行分类, 分块管理.
AssetBundle
就是Unity提供的一种针对大型项目的资源管理方案(当然, 小项目也可以使用), 将资源分类, 分块的组织起来有条不紊的管理.
AssetBundle
是将资源按照类型或者文件夹构建出一个资源包(就是所谓AssetBundle, Ab
, 资产包), 使用时先加载Ab, 然后从Ab中加载资源.
使用AssetBundle.LoadFromFile("abPath")
加载ab, 需要传入ab包全路径, 如Assets/Output/AssetBundle/AllAb/123.asset
.
使用assetBundle.LoadAsset("fileName")
从ab加载资源, 需要传入文件名(带不带后缀都可以), 或者文件全路径, 如obj.prefab
或者obj
或者Assets/Res/Prefabs/obj.prefab
.
使用assetBundle.Unload(true or false)
卸载Ab, 需要传入是否需要同时销毁从Ab中加载的资源.
使用AssetBundle.UnloadAllAssetBundles(true or false)
一次性卸载所有Ab, 参数意义与上面一致.
使用Resources.UnloadAsset(obj)
卸载从Ab中加载的资源.
使用Resources.UnloadUnusedAssets()
卸载资源所有不再使用的资源.
简单说就是:
- 先加载Ab, 然后从Ab中加载资源
- 使用
Resources
卸载从Ab中加载的资源, 当然也可以卸载不是从Ab中加载的资源 - 使用Ab卸载自己, 也可以同时一次性卸载从Ab中加载的所有资源
我们会用专门的文章讨论Ab, 这里只是一个简要说明.
这种方式提供同步和异步加载接口.
Editor下的加载和卸载方式: AssetDatabase
我们开发时大部分情况处于Editor模式下, 如果每次修改资源后都需要打Ab, 然后再调试, 这样会极大的降低开发效率, 所以在Editor模式下一般会使用AssetDatabase
或者Resources
进行资源加载和卸载.
使用AssetDatabase.LoadAssetAtPath("path")
加载资源, 提供文件全路径, 如Assets/Res/Prefabs/obj.prefab
.
使用Resources.UnloadAsset(obj)
卸载资源, 需要传入资源对象.
使用Resources.UnloadUnusedAssets()
卸载资源所有不再使用的资源.
这里简单提一下, 早期是不存在AssetDatabase
这种资源管理方式的, 它是建立在Resources
的基础之上, 在某些Unity版本中, Resources
还保留了部分AssetDatabase
接口, 只是被标记为弃用了.
当然, AssetDatabase
还有很多其它接口, 我们将在其它文章讨论.
资源(Resource)和资材(Asset)
Unity中所有对象都可以被称为资源(Resource), 包括静态的和动态的.
其中静态的资源, 就是说可以持久化的资源, 被单独称为资材(Asset), 资材本身也是一种资源.
动态的资源就是游戏运行过程中, 动态生成的对象. 这些对象可以使用资材, 然后序列化下来变成新的资材.
简单的说就是:
- 使用资材相关接口加载资材, 产生资材的引用对象:
obj = Resources.Load(...)
obj = assetbundle.LoadAsset(...)
obj = AssetDatabase.LoadAssetAtPath(...)
- 使用资源卸载接口卸载资材的引用对象:
Resources.UnloadAsset(obj)
Resources.UnloadUnusedAssets()
- 或者卸载Ab的时候, 顺便卸载资材的引用对象
assetBundle.Unload(true)
AssetBundle.UnloadAllAssetBundles(true)
但是这里有一类特殊的资材, 包括:
- 游戏对象(
GameObject
)或者组件(Component
): 以预制或者模型等形式存在 - AssetBundle
这一类资材通常需要实例化后使用(AssetBundle
除外), 且没有单独的卸载接口, 只能进行批量卸载, 其的正确卸载方式如下:
- 销毁其实例化出来的游戏对象:
Object.Destroy(obj); obj = null;
- 使用
Resources.UnloadUnusedAssets()
卸载 - 或者使用
assetBundle.Unload(true)
卸载
总结
今天简单的给大家介绍了下Unity中资源相关的基础概念, 只是提纲挈领的给大家一个先期印象, 详细的内容请参考官方文档或者后续的文章.
未来几篇文章会讨论我们资源管理的主要方式, AssetBundle
, 从打包, 同步加载, 异步加载, 卸载和简单使用, 请大家继续关注.
好了, 今天的内容就是这些, 希望对大家有所帮助.