Unity 资源管理基础知识
各类型资源以及导入面板相关参数
Unity 是一款强大的跨平台游戏开发引擎,它支持多种类型的资源,这些资源可以被用于构建游戏场景、动画、交互以及音效等。以下是一些常见的 Unity 资源类型及其用途:
纹理和图像 (Textures and Images)
包括 BMP, TIF, TGA, JPG, PNG, PSD 等格式,用于材质、UI 元素或贴图。
Inspector 面板:
Texture Type
Default: 这是用于所有纹理的最常用设置。此选项可用于访问大多数纹理导入属性。
Normal map: 选择此选项可将颜色通道转换为适合实时法线贴图的格式。
Editor GUI and Legacy GUI: 在任何 HUD 或 GUI 控件上使用纹理.
Sprite(2D and UI): 在 2D 游戏中使用该纹理作为精灵.
Cursor: 将纹理用作自定义游标.
Cookie: 此选项可通过基本参数来设置纹理,从而将其用于场景光源的剪影.
光照贴图(Light map): 允许将纹理编码为特定格式(RGBM 或 dLDR,具体取决于平台)并通过后期处理步骤对纹理数据进行处理(推拉式扩张通道)
Single Channel: 纹理中只需要一个通道
各属性解释来自unity 手册
子选择参考unity 手册
模型 (Models)
.fbx, .obj, .dae 等格式的 3D 模型,用于游戏中的物体和角色。
Model
一个 3D 模型可表示角色、建筑物或家具。在这些情况下,Unity 从单个模型文件创建多个资源。在 Project 窗口中,主导入对象是模型预制件。通常,该模型预制件还会引用多个网格对象。

Rig
一个骨架 (Rig)(有时称为 skeleton(骨骼框架))包含一组以层级视图排列的变形体 (deformer),这些变形体在 3D 建模应用程序(如 Autodesk® 3ds Max® 或 Autodesk® Maya®)中创建的一个或多个模型上对网格(有时称为皮肤)进行动画化。对于__人形 (Humanoid) 和通用 (Generic)(非人形)模型,Unity 会创建 Avatar 来使导入的骨架与 Unity 游戏对象 (GameObject) 协调。
Animation Type 功能 None 没有动画 Legacy 旧版动画 Generic 通用模型(非人形) Humanoid 人形模型 Animation
可以定义一组帧上发生的任何不同姿势(例如行走、奔跑甚至空闲状态(从一只脚移动到另一只脚))的序列作为动画剪辑。可以对任何具有相同骨架的模型重用剪辑。通常,单个文件包含多个不同的动作,可将每个动作定义为特定的动画剪辑。参数详解
Materials
可以提取材质和纹理或将它们嵌入模型中。还可以调整材质在模型中的贴图方式。
音频 (Audio)
包括 WAV, MP3, OGG 等格式的声音文件,用于背景音乐和音效。
面板参数解释
视频 (Video)
视频文件可以用于过场动画或 UI 元素,例如.mp4 或.webm 格式。视频参数解释.
使用 VideoPlayer 组件控制播放视频,组件参数解释
脚本 (Scripts)
C#或 JavaScript 编写的代码文件,用于控制游戏逻辑和行为。
材质 (Materials)
包含着色器设置和纹理引用,用于渲染物体表面。
动画 (Animations)
通过 Unity 的动画系统创建的动画剪辑,用于角色或对象的动作。
参数详解
预制件 (Prefabs)
预先设置好的游戏对象实例,可以多次重复使用。
粒子系统 (Particle Systems)
用于创建动态效果如火焰、烟雾或火花。
粒子系统模块
网格 (Meshes)
定义模型的几何形状,通常与模型文件一起导入。
着色器 (Shaders)
控制如何渲染物体的光照和颜色,可以是内置的也可以是自定义的。
字体 (Fonts)
用于 UI 文本显示,可以是位图或动态字体。
Font assets
场景 (Scenes)
游戏世界的布局,包含游戏对象和相机。
物理材质 (Physics Materials)
控制物理碰撞的摩擦力和弹力。
Physic Mat
天空盒 (Skyboxes)
通常是六面立方体贴图,用于模拟远处的天空和环境。
光照贴图 (Lightmaps)
预计算的光照数据,用于提高渲染效率。
动画控制器 (Animator Controllers)
用于管理复杂的动画状态和过渡。
输入映射 (Input Axes)
定义玩家输入的映射,如移动和跳跃。
资源文件 (Resource Files)
可以是 JSON、XML 或其他格式的数据文件,用于存储游戏数据。
AssetBundle 打包和加载
AssetBundles 是 Unity 引擎中用于资源管理的一种机制,主要用于在运行时从外部加载游戏资源,如纹理、模型、音频文件等。这种机制允许开发者将游戏资源打包成独立的文件,然后在游戏运行时按需下载和加载这些文件,从而实现资源的动态管理和优化。
分配资源
选择可打包资源,即如纹理、模型、音频文件、预制件、场景等,进入 inspector 窗口
在 inspector 窗口中选择资源分配的 AssetBundle 包名,可以以文件夹形式

第一个参数为包名,第二个参数为后缀
构建 AssetBundle
在 Assets 文件夹中创建一个名为 Editor 的文件夹,并将包含以下内容的脚本放在该文件夹中:
using UnityEditor; |
BuildAssetBundles()参数解释:
| 参数 | 解释 |
|---|---|
| outputPath | 输出路径 |
| assetBundleOptions | 构建选项 |
| BuildTarget | 目标平台 |
| 常用构建选项: |
- None:默认构建选项,使用 LZMA 压缩方式
- UncompressedAssetBundle:不压缩
- ChunkBasedCompression: 按块级压缩,即使用 LZ4 压缩方式
加载 AssetBundle
在使用 AB 包中的资源时,需要先将 AB 包加载出来,以下包含三种常用的加载方式,可以选择使用同步加载或者异步加载,异步加载需要使用协程
- AssetBundle.LoadFromMemoryAsync
此函数采用包含 AssetBundle 数据的字节数组。也可以根据需要传递 CRC 值。如果捆绑包采用的是 LZMA 压缩方式,将在加载时解压缩 AssetBundle。LZ4 压缩包则会以压缩状态加载。
以下是如何使用此方法的一个示例:
using UnityEngine; |
- AssetBundle.LoadFromFile
从本地存储中加载未压缩的捆绑包时,此 API 非常高效。如果捆绑包未压缩或采用了数据块 (LZ4) 压缩方式,LoadFromFile 将直接从磁盘加载捆绑包。使用此方法加载完全压缩的 (LZMA) 捆绑包将首先解压缩捆绑包,然后再将其加载到内存中。
void Start() |
异步加载示例
IEnumerator LoadAssetBundlesAsync(string abName,string resName) |
- UnityWebRequestAssetBundle 的 DownloadHandlerAssetBundle (Unity 5.3 或更高版本)
UnityWebRequestAssetBundle 有一个特定 API 调用来处理 AssetBundle。首先,需要使用 UnityWebRequestAssetBundle.GetAssetBundle 来创建 Web 请求。返回请求后,请将请求对象传递给 DownloadHandlerAssetBundle.GetContent(UnityWebRequestAssetBundle)。GetContent 调用将返回 AssetBundle 对象。
下载捆绑包后,还可以在 DownloadHandlerAssetBundle 类上使用 assetBundle 属性,从而以 AssetBundle.LoadFromFile 的效率加载 AssetBundle。
void Start() |
依赖关系
ab 包依赖关系:
在一个 ab 包中的资源依赖其他 ab 包中的某个资源,比如 ab1 中的 model 使用了 ab2 中的 material,
使用时如果只加载 ab1 然后使用资源 model,会出现依赖的 material 丢失的情况
解决:1.依赖文件放在同一包下。2.加载 ab1 时同时加载 ab2(不用指定,ab2 加载出来后依赖它的资源会自动使用)
//明确依赖的ab包
//AssetBundle ab2 = AssetBundle.LoadFromFile("AssetBundles/PC/material");
//问题: 一个包中的资源可能会依赖许多其他包中的资源
//解决: 使用主包寻找依赖关系批量加载(主包就是构建ab包时自动生成的与文件夹名同名的包,内部记载了各包之间的关系)
//依赖包的关键知识:利用主包 获取依赖信息
//1.加载主包
AssetBundle abMain = AssetBundle.LoadFromFile("AssetBundles/PC/PC");
//2.加载主包中的固定文件
AssetBundleManifest abManifest = abMain.LoadAsset("AssetBundleManifest", typeof(AssetBundleManifest)) as AssetBundleManifest;
//3.从固定文件中获取依赖信息(名字)
string[] strs = abManifest.GetAllDependencies("tt");
//4.加载依赖包
for (int i = 0; i < strs.Length; i++)
{
//print(strs[i]);
AssetBundle.LoadFromFile("AssetBundles/PC/"+strs[i]);
}
加载资源
加载资源也包含同步加载和异步加载,可以加载包中的一个资源,也可以加载包中的所有资源
通用方式:
T objectFromBundle = bundleObject.LoadAsset
(assetName);
T objectFromBundle = bundleObject.LoadAllAssets();
由于 Lua 中不支持泛型,使用:
Object cube = ab.LoadAsset(“Cube”, typeof(GameObject));
Object[] objects = ab.LoadAllAssets(typeof(GameObject));
还有一种需要资源名称,但是可能会取到 ab 包中同名的不同类型文件
GameObject obj = ab.LoadAsset
(“RPGHeroHP”);
Object[] objects = ab.LoadAllAssets();
卸载 AssetBundle
何时加载和卸载 AssetBundle 非常重要。不正确地卸载 AssetBundle 会导致在内存中复制对象或其他不良情况,例如缺少纹理。
关于 AssetBundle 管理的最需要了解的是何时调用 AssetBundle.Unload(bool) , 或者 AssetBundle.UnloadAsync(bool) , 以及应该将 true 还是 false 传递到函数调用中。Unload 是一个非静态函数,可用于卸载 AssetBundle。此 API 会卸载正在调用的 AssetBundle 的标头信息。该参数指示是否还要卸载通过此 AssetBundle 实例化的所有对象。
通常,使用 AssetBundle.Unload(false) 不会获得理想的情况。大多数项目应该使用 AssetBundle.Unload(true) 并采用一种方法来确保对象不会重复。两种常用方法是:
在应用程序生命周期中具有明确定义的卸载瞬态 AssetBundle 的时间点,例如在关卡之间或在加载屏幕期间。
维护单个对象的引用计数,仅当未使用所有组成对象时才卸载 AssetBundle。这允许应用程序卸载和重新加载单个对象,而无需复制内存。
还提供一个静态方法来卸载所有 AB 包
//卸载全部 ab 包,参数为 true 时表示连同 ab 包生成的资源一起卸载,false 只卸载包,资源保留
AssetBundle.UnloadAllAssetBundles(true);
其他
AssetBundleBrowser
GitHub 上下载AssetBundleBrowser
或者在项目 PackageManager 中选择选择 Add package from git URL,输入 URL:
https://github.com/Unity-Technologies/AssetBundles-Browser.git
安装成功后就可以在 Windows->AssetBundleBrowser 中打开面板
面板中可以看到以及分类好的包体资源以及相关信息
确认无误后就可以在 Build 面板中进行包体构建
主要参数包括构建平台,输出路径,是否清空文件夹在构建,复制到 StreamingAssets 文件夹下以及压缩方式等。更多细节可以官网查看
生成的 AB 包文件

AssetBundle 文件
其中包含在运行时为了加载资源而需要加载的内容。
AssetBundle 文件是一个存档,在内部包含多个文件。此存档的结构根据它是 AssetBundle 还是场景 AssetBundle 可能会略有不同。以下是普通 AssetBundle 的结构:
场景 AssetBundle 与普通 AssetBundle 的不同之处在于,它针对场景及其内容的串流加载进行了优化。清单文件
对于生成的每个包(包括附加的 Manifest bundle),都会生成一个相关的清单文件。
清单文件的扩展名为.manifest,可以用任何文本编辑器打开。
它包含诸如循环冗余校验(CRC)数据和 bundle 的依赖项数据之类的信息。
AssetBundle 压缩方式
压缩类型:
- LZ4:这是 Unity 默认使用的压缩方法,提供快速的压缩和解压速度,同时具有较好的压缩比。LZ4 非常适合用于游戏资源,因为它能在压缩和解压速度与压缩比率之间取得良好的平衡。使用哪个资源就解压哪个资源,读取快,内存略大。
- LZMA:提供更高的压缩比率,但压缩和解压速度较慢。如果你的 AssetBundles 非常大,并且下载速度不是主要瓶颈,可以考虑使用 LZMA。使用一个资源需要解压整个数据流,读取慢,内存小。
- No Compression:不使用任何压缩。虽然这会导致更大的文件大小,但在某些情况下可能更优,比如对于一些小文件或者已经高度压缩的资源(如 PNG 图像)。不用解压,读取快,内存大
压缩策略
- 按需压缩:并非所有的资源都需要压缩。例如,一些小的资源文件可能在压缩后的大小变化不大,甚至可能因为额外的压缩和解压开销而变慢。因此,识别哪些资源应该被压缩,哪些不应该,是很重要的。
- 预热压缩:在游戏启动时预加载一些关键的 AssetBundles,可以避免玩家在游戏过程中遇到长时间的加载等待。这种预加载通常使用 LZ4 压缩,因为它能够快速解压。
分组策略
因为在 unity 中给一个资源配置了 AssetBundle,系统会自动将该资源依赖的其他资源附加到当前 AB 包中,只是不会表现出来.如果现在有另一个资源也依赖这个资源,打包时在这个包中也会自动添加一个依赖资源,这就导致了资源重复,从而导致浪费内存。所以需要合理的分组策略将资源打包成不同的包,比如将共同依赖的资源打包成一个独立的包,那么依赖它的包就不会自动再打包一次了。
常用分组策略:
逻辑实体分组
逻辑实体分组是指根据资源所代表的项目功能部分将资源分配给 AssetBundle。这包括各种不同部分,比如用户界面、角色、环境以及在应用程序整个生命周期中可能经常出现的任何其他内容。
类型分组
根据此策略,可以将相似类型的资源(例如音频轨道或语言本地化文件)分配到单个 AssetBundle。
并发内容分组
并发内容分组是指将需要同时加载和使用的资源捆绑在一起。可以将这些类型的捆绑包用于基于关卡的游戏(其中每个关卡包含完全独特的角色、纹理、音乐等)。有时可能希望确保其中一个 AssetBundle 中的资源与该捆绑包中的其余资源同时使用。依赖于并发内容分组捆绑包中的单个资源会导致加载时间显著增加。您将被迫下载该单个资源的整个捆绑包。
无论遵循何种策略,下面这些额外提示都有助于掌控全局:
- 将频繁更新的对象与很少更改的对象拆分到不同的 AssetBundle 中
- 将可能同时加载的对象分到一组。例如模型及其纹理和动画
- 如果发现多个 AssetBundle 中的多个对象依赖于另一个完全不同的 AssetBundle 中的单个资源,请将依赖项移动到单独的 AssetBundle。如果多个 AssetBundle 引用其他 AssetBundle 中的同一组资源,一种有价值的做法可能是将这些依赖项拉入一个共享 AssetBundle 来减少重复。
- 如果不可能同时加载两组对象(例如标清资源和高清资源),请确保它们位于各自的 AssetBundle 中。
- 如果经常同时加载的 AssetBundle 少于 50%,可以考虑拆分 AssetBundle
- 考虑将多个小型的(少于 5 到 10 个资源)但经常同时加载内容的 AssetBundle 组合在一起
- 如果一组对象只是同一对象的不同版本,请考虑使用 AssetBundle 变体
安全性和完整性
- 采用安全协议下载
- CRC 校验和
- 用户生成的内容
Addressable 简单使用
Unity 的 Addressables 系统是一种先进的资源管理和加载解决方案,旨在提供更加灵活和高效的资源处理方式。Addressables 系统克服了传统 AssetBundles 的一些限制,提供了更强大的功能和更好的性能,特别是在处理大量资源和复杂依赖关系时。
准备资源
下载 Addressables 插件
在 Package Manager 中找到 Addressables 插件进行安装
创建默认 Setting
打开 Windows->Asset Management->Addressable ->Group

点击 Create Addressables Settings 后会在 Asset 文件夹下自动生成一个 AddressableAssetsData 文件夹,里面包含了对 Addressable 的配置文件等
构建资源
使用 Addressables 系统提供的构建工具,将资源打包成适合运行时加载的格式。
点击可打包资源,勾选顶部的 Addressable 选项或拖动资源到 Addressables Group 窗口中对资源进行打包
- 新建 Group
在 Addressable Group 窗口上方 New-> Packed Asset 或者在窗口空白处右击鼠标点击 Create New Group -> Packed Asset
每次新建一个 Group,在 Assets/AddressableAssetsData/AssetGroups/Schemas 目录下会生成一个对应的配置文件
- Group
Group 是可寻址系统的主要组织单位,要控制 Unity 在内容构建期间处理资源的方式,请将可寻址对象组织成组,并根据需要为每个组分配不同的设置。
- Label
标签在可寻址系统中有多种用途,包括:
- 可以使用一个或多个标签作为键来标识要在运行时加载的资产。
- 可以根据分配的标签将组中的资产打包到 AssetBundle 中。
- 可以使用“组”窗口的筛选框中的标签来帮助查找已标记的资产
- 资源打包
资源配置完成后点击 Addressable->Build->New Build->Default Build Script 即可构建 bundle 包
默认情况下系统会将每一个 Group 打包成一个 bundle 文件,但是根据需要可以修改配置文件,将文件单独打包,或者按标签打包
默认情况下 bundle 包都是保存在本地的,也可以通过配置文件修改位置
- 修改 LoadPath&BuildPath
在 Addressable Group 窗口中 Tools->Window->Profiles 或者在 Unity 中的 Windows->Asset Management->Addressables->Profiles
加载资源
在运行时,使用 Addressables API 来异步加载资源。这可以是按需加载单个资源,或者加载一组相关的资源。
加载资源方式
- 通过 Addressables Name 加载
Addressable 提供了许多加载资源的方式,详情见Addressable API
void Start() |
AsyncOperationHandle 中包含了资源的加载信息
如果是需要直接用来实例化的游戏对象,Addressable 还提供了另一个方法
Addressables.InstantiateAsync(“RPGHeroHP”);
- 通过 AssetReference 加载
public AssetReference assetReference; |
- 通过 Label 加载
public AssetLabelReference labelReference;//在Inspector面板中可以设置 |
- 加载场景
//加载场景 |
- 加载资源路径
Addressables.LoadResourceLocationsAsync(assetReference, typeof(GameObject)).Completed +=(handle)=> |
Addressables 三个加载模式
Use Asset Database (fastest)
这种模式是最快的加载模式,因为它直接使用 Unity 编辑器中的 AssetDatabase 来加载资源。在这种模式下,资源不会被打包成 AssetBundles,而是以原始的形式存储在磁盘上。因此,资源的加载速度非常快,因为不需要解包或解压缩的过程。 这个模式最适合在开发阶段使用,因为它是最快的,可以提供即时的反馈,帮助开发者迅速迭代和测试。然而,由于资源没有被打包,这种模式不适合最终的构建或部署,因为它会导致资源的大小和数量直接暴露给用户,容易被破解或修改。
Simulate Groups (advanced)
这种模式模拟了 AssetBundles 的行为,但资源实际上并未被打包。它提供了比 Use Asset Database 更高级的功能,如资源分组和依赖管理,同时仍然保持较快的加载速度。 在 Simulate Groups 模式下,Addressables 系统会像处理 AssetBundles 一样处理资源,包括处理资源的依赖关系,但所有这些操作都在不实际打包资源的情况下进行。这使得它成为开发和调试阶段的理想选择,因为你可以在接近生产环境的条件下测试资源的加载和管理,而无需等待打包过程。
Use Existing Build (requires built groups)
这是最接近实际生产环境的加载模式,因为它要求资源已经被打包成 AssetBundles。在 Use Existing Build 模式下,Addressables 系统将从已构建的 AssetBundles 中加载资源,这通常是最终构建和部署时所采用的方式。 这种模式提供了最好的性能和安全性,因为资源被打包并压缩,减少了存储空间和下载时间。同时,由于资源被加密,它也提供了更好的保护,防止资源被轻易访问或修改。
选择加载模式
选择哪种加载模式取决于你的项目阶段和需求。在开发和测试阶段,通常会选择 Use Asset Database 或 Simulate Groups 模式,因为它们提供了更快的迭代速度。而在最终构建和部署阶段,应该使用 Use Existing Build 模式,以确保资源的安全性和最佳的性能。
管理资源生命周期
Addressables 提供了 API 来管理资源的生命周期,包括缓存和卸载资源
资源释放
调用 API
Addressables.Release(handle);
如果是 AssetReference,则用
assetReference.ReleaseAsset();


