Unreal蓝图优化
减少节点连接数量,尤其是减少循环和遍历的操作
(预制体并不会有性能损耗)
Tick优化
首先就是尽量不用
Tick
,不需要的都关掉。有些时候并不需要每帧都更新,比如UMG绑定数据可以改用事件来更新(注意在C++里如果要更新
ProgressBar
的Percent
属性,不是直接给他赋值,而是要调用SetPercent
,否则实际显示并不会更新)直接用用
Timer
代替Tick
。初始的时候就设置禁用Tick
,由Timer
进行每秒更新仍然使用
Tick
- 用
Timer
每秒检测与player的距离,根据距离更新频率SetActorTickInterval
,当距离达到一定阈值时可SetTickingAllowed
为false
- 用
Timer
每秒检测是否可以被player看见,根据WasRecentlyRendered
来设置更新频率
- 用
使用Timer比较多的时候可以考虑再加个随机延迟时间
RandomFloatInRange
,防止在同一时间内进行大量更新
使用材质实现简单的动画(GPU),而不是用蓝图实现(CPU)。像旋转、淡入淡出都可以用材质实现。
关于资源加载
C++类会在初始化时全部加载,而蓝图类作为资源只会在用到的时候(Cast也算)加载。为防止蓝图加载太多内容,可以尝试把蓝图拆分为父子类。
推荐的做法是建立一个C++基类,然后由一个蓝图继承,之后再由此蓝图派生出不同的子类,在这些子类中才引用资源。可以通过
ReferenceViewer
查看引用关系蓝图库中也不要引用外部资源。比如要生成粒子效果,那么粒子的类型应该也由参数传入,而不是写在函数里。
使用不同的游戏模式帮助区分引用,如
GameMode_Game
和GameMode_Menu
;使用异步资源加载
AxyncLoadAsset
使用
Maps
保存软引用,要用的时候通过键进行索引并异步加载
关于类型转换
- 跟资源加载一样,如果有引用到其它蓝图也会导致编译时间加长。这里引用包括
Cast
和==
- 应该让比较少用到的功能引用经常用到的功能,因为后者可能已经在内存中了
- 可以通过C++编写蓝图函数库作为蓝图之间的桥梁(蓝图之间通过C++函数进行通信),从而避免不必要的类型转换
- 父类声明事件,子类进行实现,那么就可以转换为父类进行调用,或者调用接口
- 用
ActorHasTag
代替类型检测
- 跟资源加载一样,如果有引用到其它蓝图也会导致编译时间加长。这里引用包括
由于可能存在循环引用(CircularReferences,属于RaceCondition),在类初始化时可能无效,需要使用
Delay
或者检查IsValid
来防止错误蓝图调试:Window > Develop Tools > Blueprint Debugger
控制台命令:
state game
,state fps
,state unit
,state rhi
,dumpticks
使用C++(大型项目里大约80%是C++)。有些时候用蓝图不容易或者无法实现,比如存档、平台特殊功能、特殊硬件、SDK以及网络相关等,就要用C++。关于性能方面,公用函数、每帧更新还有些复杂功能都应该用C++实现
不同打包模式性能差别很大
蓝图使用小技巧
- 减少函数的输入输出引脚
- 暴露变量
ExposeOnSpawn
、ExposeToCinematics
- 在编辑器里点击按钮调用函数
CannInEditor
- 删掉多余变量
Edit > DeleteUnusedVaiables
- 显示3D控件
Show3DWidget
,在视口里修改蓝图的向量 - 不用的蓝图类标记为
ClassOptions > Deprecate
- 使用蓝图书签(五角星形),方便在大型工程中快速索引
- 使用
StringTables
,方便进行文本本地化 - 使用
Maps
,上面说到资源加载时提过 - 使用
Sets
,用来保存唯一东西,而不用手动遍历数组检查是否重复 - 使用
IsValid
,防止无效错误,前面也提了。