3D 模型

Unity 支持多种标准和特有的模型格式,如 .fbx.dae.dxf 以及 .obj

Unity 对 .fbx 支持最好,在内部使用 .fbx 文件作为导入链。因此,最佳实践是尽可能使用 .fbx 模型。

模型最佳实践

创建最佳性能模型的技巧:

  • 最小化多边形数量(取决于目标质量和目标平台)
  • 尽可能减少材质的使用
  • 使用单蒙皮网格渲染器,以激活 Unity 的可见性剔除和包围体积更新
  • 尽可能减少骨骼数量
  • 保持 FK 和 IK 的分离,以便导入后删除冗余的 IK 节点

创建与动画配合良好的模型:

  • 使用结构良好的拓扑结构
  • 使模型的大小与 1m³ 的立方体成正确的比例
  • 确保模型的脚部位于模型本地原点
  • 对双足模型应用 T-pose

导入人形模型

人形模型(Humanoid)要求:

  • 至少 15 块骨头
  • 使用标准一致的身体部分命名

导入人形动画模型:

  1. Rig 改为 Humanoid,并创建 Avatar
  2. 确保 Avatar 映射正确
  3. 通过 Muscles & Settings 配置模型的肌肉
  4. 在 Avatar 窗口选择 Mapping > Save 来存储模板(可选)
  5. Animation 选项卡中导入动画

导入通用模型

通用模型(Generic)要求:

  • 包含根节点,以定义质心

导入通用动画模型:

  1. Rig 改为 Generic
  2. 定义 Avatar Mask 以限制动画
  3. 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:强制单声道,多声道在打包前混合为单声道音轨
  • 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# 调用这些库中的函数。

使用原生插件的步骤:

  1. 使用 C-based 语言编写函数
  2. 编译为库文件
  3. 在 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 ());
   }
}

参考

插件类型

以下类型被 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

启动时加载

  1. 在插件中实现 UnityPluginLoad
  2. 在编辑器中勾选 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 等。