Unity 性能优化 之 编辑器创建资源优化( 工作流 | 场景 | 预制体)
Unity 之 性能优化 -- 工作流 | 场景 | 预制体
- 工程目录与Assets目录设置
- Unity工程目录结构及用途
- Unity Assets目录中的特殊文件夹及用途
- Assets目录结构设计(仅供参考)
- 资源导入工作流
- 手动编写工具
- 利用Presets功能
- 利用AssetGraph工具
- 场景
- 场景结构设计原则
- 预制体
- 预制体Prefab
- 使用预制体的好处
- 嵌套预制体与单预制体相比的优点与缺点
- 使用Prefab变体的一些限制
工程目录与Assets目录设置
Unity工程目录结构及用途
-
Asset文件夹:用来存储和重用的项目资产
-
Library文件夹:用来存储项目内部资产数据信息的目录**
-
Packages文件夹:用来存储项目的包文件信息
-
Project Settings文件夹:用来存储项目设置的信息
-
UserSettings文件夹:用来存储用户设置信息
-
Temp文件夹:用来存储使用Unity编辑器打开项目时的临时数据,一旦关闭Unity编辑器也会被删除
-
Logs文件夹:用来存储项目的日志信息(不包含编辑器日志信息)
Unity Assets目录中的特殊文件夹及用途
- Editor文件夹(可以多个)
- Editor Default Resources文件夹(根目录唯一)
- Gizmos文件夹(根目录唯一)
- Plugins文件夹(2019后已无,但仍可使用,仍能保障其中代码编译的优先顺序)
- Resources文件夹(可以多个,强烈建议正式项目中一定不要有此文件夹)
- Standard Assets文件夹(根目录唯一,其中代码编译优先)
- StreamingAssets文件夹(根目录唯一)
- 忽略导入的文件夹
- 隐藏的文件夹
- 以*“.”*开头的文件和文件夹
- 以*“~”*结尾的文件和文件夹
- 扩展名为cvs的文件和文件夹
- 扩展名为*.tmp**的文件夹*
Assets目录结构设计(仅供参考)
一级目录设计原则:
- 目录尽可能少
- 区分编辑模式与运行模式
- 区分工程大版本
- 访问场景文件、全局配置文件便捷
- 不在一级目录做资源类别区分,只有Video类视频建议直接放到StreamAssets下
二级目录设计原则:
- 只区分资源类型
- 资源类型大类划分要齐全
- 不做子类型区分
- 不做功能区分
- 不做生命周期区分
三级目录设计原则:
- Audio/Texture/Models三级目录做子类型区分
- 其他类型资源可按功能模块/生命周期区分
四级目录设计原则:
- 只有Audio/Texture/Models做四级目录,可按功能模块/生命周期划分
资源导入工作流
资源导入工作流的三种方案
手动编写工具
优点: 根据项目特点自定义安排导入工作流,并且可以和后续资源制作与大包工作流结合
缺点: 存在开发和维护成本,会让编辑器菜单界面变得复杂,对新人理解工程不友好
适合类型: 大型商业游戏团队
- AssetPostprocessor:
编写编辑器代码继承AssetPostprocesser对象自定义实现一些列OnPreprocessXXX接口修改资源导入设置属性
伪代码:
public class XXXAssetPostprocessor : AssetPostprocessor
{public void OnPreprocessXXXAsset(){XXXAssetImporter xxxImporter = (XXXAssetImporter)assetImporter;xxxImporter.属性 = xxx...xxxImporter.SaveAndReimport();}
}
参考资料: https://docs.unity3d.com/
- AssetsModifiedProcessor(新试验接口):
资源被添加、删除、修改、移动时回调该对象的OnAssetsModified接口
void OnAssetsModified(string[] changedAssets, string[] addedAssets, string[] deletedAssets, AssetMoveInfo[] movedAssets)
{...
}
利用Presets功能
优点: 使用简单方便,只需要Assets目录结构合理规范即可
缺点: 无法和后续工作流整合,只适合做资源导入设置。
适合类型: 小型团队或中小规模项目
参考资料:https://docs.unity3d.com/cn/2021.2/Manual/DefaultPresetsByFolder.html
利用AssetGraph工具
优点: 功能全,覆盖Unity资源工作流全流程,节点化编辑,直观
缺点: 有一定上手成本,一些自定义生成节点也需要开发,不是Unity标准包,Unity新功能支持较慢。
适合类型: 任何规模项目和中大型团队
AssetGraph仓库地址:https://github.com/Unity-Technologies/AssetGraph
场景
场景结构设计原则
- 合理设计场景一级节点的同时,避免场景节点深度太深,一些代码生成的游戏对象如果不需要随父节点进行Transform的,一律放到根节点下。
- 尽量使用Prefab节点构建场景,而不是直接创建的GameObject节点
- 避免DontDestroyOnLoad节点下有太多生命周期过长或引用资源过多的复杂节点对象。Additve模式添加的场景要尤为注意。
- 最好为一些需要经常访问的节点添加tag,静态节点一定要添加Static标记。
注意:复杂场景中,对于设置好Tag的节点,使用FindGameObjectWithTag方法取查找该节点更高效
预制体
预制体Prefab
Unity中的预制体是用来存储游戏对象、子对象及其所需组件的可重用资源,一般来说预制体资源可充当资源模版,在此模版基础上可以在场景中创建新的预制体实例。
使用预制体的好处
- 由于预制体系统可以自动保持所有实例副本同步,因此可以比单纯地简单复制粘贴游戏对象做到更好的对象管理。
- 此外通过预制体嵌套(Nested Prefabs)可以将一个预制体嵌套到另一个预制体中,从而创建多个易于编辑的复杂游戏对象层级视图。
- 可以通过覆盖各个预制体实例的设置来创建预制体变体(Prefabs Variant),从而可以将一系列覆盖组合在一起形成有意义预制体的变化。
嵌套预制体与单预制体相比的优点与缺点
- 优点:
- 嵌套预制体方便预制体管理,方便资源重复利用,易于统计场景复杂度
- 美术制作时可以比较合理的分配UV,和贴图利用率
- 方便关卡设计人员发挥,充分合理利用资源
- 嵌套预制体比较方便利用工具做LOD,LOD效果也比较好
- 嵌套预制体修改方便,只需修改子预制体就可以做到所有嵌套预制体同步
- 比较方便做场景遮挡剔除,可以做到精细的遮挡剔除优化效果
- 缺点:
- 手动做Bundle依赖时要按Scene方式处理,依赖关系较为复杂
- 可能会增加材质数量与Drawcall数量
- 不太适合做大规模远景对象。
- 美术与关卡设计人员要充分考虑组合复杂度与特例场景显示,避免重复性和单一性,需要更多的沟通成本
使用Prefab变体的一些限制
- 不能改变本体Prefab游戏对象 (GameObject)层级
- 不能删除本体Prefab中的游戏对象,但可以通过Deactive游戏对象来达到与删除游戏对象同样的效果
- 对于Prefab变体要保持其Override属性的变化,不能通过Apply to base把这些变化应用到本体Prefab上,这样会破坏基础Prefab的结构和功能。
本文整理自:Metaverse大衍神君《Unity性能优化》