Tick:你真的需要每帧执行吗

如果只学一个性能习惯,学这个:Tick 是昂贵的,少用。

每个 Tick 的 Actor/组件都要在场景的 Tick 列表里占一格;蓝图 Tick 还要穿越 VM 边界。场景里有 1000 个开着 Tick 的 Actor,每帧就是 1000 次调度——即使每个 Tick 函数体是空的。

三个问题自检

  1. 它必须每帧更新吗? 很多逻辑其实只在事件发生时才需要跑(受击、移动结束、状态切换)。改成事件驱动。
  2. 它必须对所有对象都 Tick 吗? 远处的敌人、屏幕外的 UI 动画,可以按重要性分级。
  3. 它的频率可以降低吗? 用 Timer(SetTimer,如 0.1s 一次)代替 Tick,多数"轮询类"逻辑足够了。

具体替代手段

Tick 的用途 替代
定期检查状态 SetTimer 轮询(0.1~0.5s)
等待条件成立 事件/委托(条件变化时广播)
移动 FloatingPawnMovement / ProjectileMovement(内置插值与网络同步)
UI 定时刷新 事件驱动 + 动画曲线
必须每帧但看距离 按距离分级(近处 Tick、远处关)

蓝图 Tick 的两个隐藏成本

  1. 事件图表本身的开销:Tick 节点即使没连线也存在;连了几十个节点的 Tick 图表,每帧穿越 VM。
  2. Tick 里的 Get/Cast/FindComponent:每帧重复查找,参见上页的"缓存"方案。

一个真实案例

80 个小怪的"回血逻辑"原本写在蓝图 Tick(每帧检查血量、判断是否脱战、加血)。改为:受击/脱战由事件驱动,回血用 0.5s Timer。CPU 从 ~9ms/帧降到 ~2ms/帧,而行为表现一模一样。

项目级自查

  • 蓝图里 Event Tick 用了多少?可以开 stat Blueprint(或者用 Insights)看蓝图 VM 开销分布。
  • 用 Unreal Insights 的 Frames 视图定位:哪个对象的 Tick 在热点里。

相关官方资料:Gameplay 定时器

本章小结

  • Tick 是项目变卡的第一大来源:能停的 Tick 停,能降频的降频,能事件化的事件化。
  • 替代手段:SetTimer 轮询、事件/委托驱动、MovementComponent、距离分级。
  • 蓝图 Tick 额外成本:VM 穿越 + 图表内重复查找(缓存解决)。