3D 模型
Unity 支持多种标准和特有的模型格式,如 .fbx
、.dae
、.dxf
以及 .obj
。
Unity 对 .fbx
支持最好,在内部使用 .fbx
文件作为导入链。因此,最佳实践是尽可能使用 .fbx
模型。
模型最佳实践
创建最佳性能模型的技巧:
- 最小化多边形数量(取决于目标质量和目标平台)
- 尽可能减少材质的使用
- 使用单蒙皮网格渲染器,以激活 Unity 的可见性剔除和包围体积更新
- 尽可能减少骨骼数量
- 保持 FK 和 IK 的分离,以便导入后删除冗余的 IK 节点
创建与动画配合良好的模型:
- 使用结构良好的拓扑结构
- 使模型的大小与 1m³ 的立方体成正确的比例
- 确保模型的脚部位于模型本地原点
- 对双足模型应用 T-pose
导入人形模型
人形模型(Humanoid)要求:
- 至少 15 块骨头
- 使用标准一致的身体部分命名
导入人形动画模型:
- 将
Rig
改为 Humanoid,并创建 Avatar - 确保 Avatar 映射正确
- 通过
Muscles & Settings
配置模型的肌肉 - 在 Avatar 窗口选择
Mapping
>Save
来存储模板(可选) - 在
Animation
选项卡中导入动画
导入通用模型
通用模型(Generic)要求:
- 包含根节点,以定义质心
导入通用动画模型:
- 将
Rig
改为 Generic - 定义
Avatar Mask
以限制动画 - 在
Animation
选项卡中导入动画
图像文件
Unity 将图像文件作为纹理或者精灵导入。支持常见的图像文件类型,如 BMP、EXR、GIF、HDR、IFF、PICT、TIFF、TGA、JPG、PNG 以及 PSD。将分层 PSD 导入项目时,Unity 会将其扁平化,将分层图像保存为单层图像。
当图像的宽高为 2 的幂时可以获得更好的性能,NPOT(非 2 的幂)图像会占用更多的内存,并且 GPU 的采样速度也会变慢。当平台不支持 NPOT 纹理大小时,Unity 会将其缩放并填充到下一个幂。此过程会占用内存并使加载速度变慢。
纹理导入设置窗口分为以下几个部分:
- Texture Type
- Texture Shape
- 类型各自的属性
- 针对平台的设置
Texture Type
类型 | 描述 |
---|---|
Default | 提供对大多数属性 |
Normal map | 适合实时法线贴图 |
Editor GUI and Legacy GUI | 适用于 HUD 和 GUI 控件 |
Sprite (2D and UI) | 适用于 2D 游戏精灵 |
Cursor | 适用于自定义鼠标光标 |
Cookie | 适用于内置渲染管线的 Light Cookie |
Lightmap | 适用于光照贴图,允许编码为 RGBM 或 dLDR 和后处理采样 |
Directional Lightmap | 适用于定向光照贴图 |
Shadowmask | 适用于阴影遮罩 |
Single Channel | 使纹理只有一个单通道 |
Texture Shape
- 2D:2D 纹理,最常见的设置
- Cube:立方体贴图,常用于天空盒或反射探针
- 2D Array:2D 纹理数组,用于某些渲染技术的优化
- 3D:3D 纹理,用于表示体积数据
类型各自的属性
当选择不同的纹理类型时,设置窗口会显示对应类型的属性,以进行更精细的调整。
针对平台的设置
在针对不同平台进行构建时,需要考虑分辨率、文件大小、内存大小、纹理质量以及目标平台压缩格式。
- Max Size:最大尺寸
- Resize Algorithm:超过 Max Size 时的缩小算法
- Mitchell:默认算法
- Bilinear:双线性插值算法,比 Mitchell 保留的细节更多。主要对那些小而清晰,并且细节很重要的图像
- Format:格式,参考特定平台的纹理格式
- Compression:压缩质量
- None:不压缩
- Low Quality:低质量,更少的内存
- Normal Quality:标准质量
- High Quality:高质量,更多的内存
- Use Crunch Compression:Crunch 有助于减少磁盘空间,虽然压缩时间长,但是解压速度快。因此,尽可能使用 Crunch
- Compressor Quality:使用 Crunch 压缩时,更高的压缩质量以为着更大的纹理和更长的压缩时间
- Split Alpha Channel:对纹理进行 alpha 分隔
- Override ETC2 fallback:对于不支持 ETC2 的安卓设备,使用另一种指定的压缩格式
音频文件
Unity 支持以下音频格式:.mp3
、.ogg
、.wav
、.aiff
、.mod
、.it
、.s3m
、.xm
。
虽然 Unity 支持多种音频文件格式,但是最好使用未压缩的音频文件格式,如 .wav
或者 .aiff
,因为在导入过程中 Unity 会应用导入设置中指定的压缩方式。
Audio Clip
导入 Unity 的任何音频文件均可以作为 Audio Clip 使用,Audio Clip 为运行时提供了一种访问音频数据的方式。
在加载实际音频数据前,可以通过 AudioClip 来访问有关音频的元信息。这些信息在导入过程中就已经提取到了 AudioClip 中。
音频设置
- Force To Mono:强制单声道,多声道在打包前混合为单声道音轨
- Normalize:在强制单声道的过程中进行音频标准化
- Load In Background:启用此选项,Clip 将在单独的线程上延迟加载,不会阻塞主线程
- Ambisonic:环绕立体声
- Load Type:运行时加载音频资源的方式
- Decompress On Load:加载后立即解压缩。对于较小的压缩声音使用此选项,以避免动态解压缩的性能开销。加载时,解压缩 Vorbis 编码的音频比保持压缩状态多 10 倍内存,对于 ADPCM 约为 3.5 倍,因此不要对大文件使用此选项
- Compressed In Memory:将音频压缩在内存中并在播放时解压缩。此选项有轻微的性能开销,特别是对 Ogg/Vorbis 压缩文件而言。对于加载时解压缩消耗过的内存的文件使用此选项,可以在 Profiler 窗口中查看 DSP CPU 的音频模块来确认消耗
- Streaming:使用最少量的内存来缓冲从磁盘增量读取并自解码的压缩数据,解压缩发生在单独的线程上。注意:即使没有加载任何音频数据,Streaming 也会产生 200KB 的开销
- Preload Audio Data:在场景加载后预加载
- Compression Format:压缩格式
- PCM:未压缩的原始音频数据,占用磁盘大,不需要解压缩,适合短音效
- ADPCM:压缩比约为 3.5,可能会引入噪音,一般适合自带噪音并且需要大量播放的声音。例如,脚步声、撞击声、武器声等
- Vorbis/MP3:高压缩率比,压缩后文件小,解压占用高,适合中长音效和音乐
- Sample Rate Setting:采样率
- Preserve Sample Rate:保持原始采样率
- Optimize Sample Rate:根据最高频自动优化采样率
- Override Sample Rate:允许手动覆盖采样率
- Quality:质量
设置建议
PC/主机
音频类型 | Background | Load Type | Preload | Compression | Quality | Sample |
---|---|---|---|---|---|---|
对话式发声 | ✔ | Memory | ✔ | Vorbis | 70 | Preserve |
非对话发声 | ✔ | Load | ✔ | Vorbis | 70 | Preserve |
环境(长) | N/A | Streaming | N/A | Vorbis | 70 | Preserve |
环境(短) | ✔ | Load | ✔ | Vorbis | 70 | Preserve |
交互 | ❌ | Memory | ✔ | PCM | N/A | Optimize |
脚步 | ❌ | Memory | ✔ | PCM | N/A | Optimize |
音乐(长) | N/A | Streaming | N/A | Vorbis | 85 | Preserve |
音乐(短) | ✔ | Memory | ✔ | Vorbis | 85 | Preserve |
音效(长) | ❌ | Load | ✔ | Vorbis | 70 | Preserve |
音效(短) | ❌ | Memory | ✔ | PCM | N/A | Optimize |
UI 音(长) | ✔ | Load | ✔ | Vorbis | 70 | Preserve |
UI 音(短) | ❌ | Memory | ✔ | PCM | N/A | Optimize |
移动设备
音频类型 | Background | Load Type | Preload | Compression | Quality | Sample |
---|---|---|---|---|---|---|
对话式发声 | ✔ | Memory | ✔ | Vorbis | 50 | Preserve |
非对话发声 | ✔ | Load | ✔ | Vorbis | 50 | Preserve |
环境(长) | ✔ | Memory | ✔ | Vorbis | 35/higher | Preserve |
环境(短) | ✔ | Load | ✔ | Vorbis | 50 | Preserve |
交互 | ❌ | Memory | ✔ | PCM/ADPCM | N/A | Preserve |
脚步 | ❌ | Memory | ✔ | PCM/ADPCM | N/A | Optimize |
音乐(长) | ✔ | Streaming | N/A | Vorbis | 70 | Preserve |
音乐(短) | ❌ | Memory | ✔ | Vorbis | 70 | Preserve |
音效(长) | ❌ | Load | ✔ | Vorbis | 50 | Preserve |
音效(短) | ❌ | Memory | ✔ | PCM/ADPCM | N/A | Optimize |
UI 音(长) | ✔ | Load | ✔ | Vorbis | 50 | Preserve |
UI 音(短) | ❌ | Memory | ✔ | PCM/ADPCM | N/A | Optimize |
其它注意事项
- 流式传输外的其它加载类型会将音频数据加载并保留在 RAM 中,直到场景卸载。手动从 RAM 删除 AudioClip 的效率非常低,并且可能会导致卡顿
- MP3 不会无缝循环,MP3 通常会在文件末尾添加静音填充,以使样本总数可以被 1152 整除。如果要使用 MP3 创建无缝循环,需要使用一定的方法
- 禁用预加载音频并且禁用后台加载,将会在第一次调用大文件音频时使主线程停止运行。
.mod
音频不存在此问题,因为.mod
在单独的线程上解码 - 当目标平台是 PS4 时,ATRAC9 格式可以提供相当高的压缩比,并且 CPU 开销比 Vorbis 或 MP3 少
- 当目标平台是 Xbox 时,XMA 格式更合适
- 还有一些中间解决方案,如 FMOD 和 Wwise 可以自己处理音频导入
文本文件
Unity 支持的文本格式有:.txt、.html、.htm、.xml、.bytes、.json、.csv、.yaml、.fnt。
二进制数据
文本资源可以用来存储二进制数据,通过为文件提供扩展名 .bytes,它可以作为文本资源加载,并通过 bytes 属性访问其中的数据。
插件 Plug-ins
在 Unity 中,通常使用脚本创建功能,但也可以用插件的形式来使用功能。Unity 支持两种插件:
- Managed plug-ins(托管插件):.NET 程序集,可以使用 .NET 库的功能。与 Unity 脚本的唯一区别是,Managed plug-ins 是由外部创建的
- Native plug-ins(原生插件):可以访问操作系统调用以及第三方代码库的功能
托管插件
托管插件是使用外部创建并编译成 DLL 的 .NET 程序集。托管插件仅包含 .NET 代码,不能访问 .NET 库不支持的功能。以下是使用 DLL 的场景:
- 使用 Unity 不支持的编译器
- 在 DLL 中添加第三方 .NET 代码
- 在没有源代码的情况下为 Unity 提供代码
使用 unsafe 代码:Edit > Project Settings > Player > Other Settings > Allow Unsafe Code
原生插件
Unity 支持 Native 插件,它们是用 C、C++ 或者 Objective-C 等语言编写的本机代码。插件允许 C# 调用这些库中的函数。
使用原生插件的步骤:
- 使用 C-based 语言编写函数
- 编译为库文件
- 在 Unity 中使用 C# 访问
using UnityEngine;
using System.Runtime.InteropServices;
class ExampleScript : MonoBehaviour {
#if UNITY_IPHONE
// On iOS plugins are statically linked into
// the executable, so we have to use __Internal as the
// library name.
[DllImport ("__Internal")]
#else
// Other platforms load plugins dynamically, so pass the
// name of the plugin's dynamic library.
[DllImport ("PluginName")]
#endif
private static extern float ExamplePluginFunction ();
void Awake () {
// Calls the ExamplePluginFunction inside the plugin
// And prints 5 to the console
print (ExamplePluginFunction ());
}
}
参考
- C# 和 Native 相互操作:Interop with Native Libraries
- 简单的插件示例:Simplest Plugin Example
- 低级渲染插件:Native Renderer Plugin
插件类型
以下类型被 Unity 视为插件:.a、.aar、.bc、.c、.cc、.cpp、.dll、.def、.dylib、.h、.jar、.jslib、.jspre、.m、.mm、.prx、.rpl、.so、.sprx、.suprx、.swift、.winmd、.xex、.xlib。
此外,以下名称结尾的文件夹将被视为打包插件,Unity 不会在文件夹内部去查找插件,而是将其视为一个整体:.androidlib、.bundle、.framework、.plugin。
识别路径
路径 | 平台 |
---|---|
Assets/…/Editor/(x86 or x86_64 or x64) | Editor only |
Assets/…/Plugins/(x86 or x86_64 or x64) | Windows, Linux and macOS |
Assets/Plugins/iOS | iOS |
Assets/Plugins/WSA/(SDK80 or SDK81 or PhoneSDK81)/(x86 or ARM) | Universal Windows Platform |
启动时加载
- 在插件中实现 UnityPluginLoad
- 在编辑器中勾选 Plugin load settings > Load on startup
程序集
程序集定义和程序集引用可以用来组织脚本。有关程序集的阅读:Assemblies in .NET。
程序集是一个 C# 代码库,其中包含由脚本定义的类和结构,并且定义了对起他程序集的引用。默认情况下,Unity 会将脚本编译到 Assembly-CSharp.dll
中。
程序集 | 描述 |
---|---|
Assembly-CSharp-firstpass | 位于 Standard Assets、Pro Standard Assets 以及 Plugins 的脚本 |
Assembly-CSharp-Editor-firstpass | 位于以上文件夹中的 Editor 文件夹下的脚本 |
Assembly-CSharp | 除上述文件外的其它脚本 |
Assembly-CSharp-Editor | 除上述文件夹外的其它文件夹下的 Editor 文件下的脚本 |
每当脚本变动时,Unity 就会重新编译脚本。
原生资产
Unity 编辑器有多种原生资源类型,可以在 Untiy 中使用编辑器功能创建这些类型的资源。如,animation、curve、gradient、mask、material、preset 等。