有一阵射击关卡掉帧,脚本里几乎没有重逻辑。Profiler 里却能看到 Transform 相关的派发很忙。原因很土:子弹对象池全部 parent 在枪口下,角色一转身,整池子弹的世界矩阵都要跟着失效。
Transform 改本地坐标时,不一定立刻重算世界矩阵。它会先做脏标记,等渲染、物理或你读取 position 时再算。父节点每帧动,子树就越脏。
后来改成的习惯
- 特效、弹道、伤害数字这类动态池,运行时放到场景根节点,需要坐标时再赋值。
- 热路径里缓存
transform.position,不要在循环里反复读属性。 - 同时改位置和旋转时用
SetPositionAndRotation,少一次原生调用。 - 层级是给编辑和逻辑分组用的,不是性能免费午餐。骨骼和 UI 有自己的结构,不要和弹道池套同一套 nested 习惯。
void Update()
{
var origin = transform.position;
for (int i = 0; i < _targets.Count; i++)
{
var delta = _targets[i].position - origin;
if (delta.sqrMagnitude < _rangeSqr)
TryLock(_targets[i]);
}
}
备忘:编辑器里为了好找,可以把池子放在空物体下;真正 Instantiation 之后,再在运行时 SetParent(null, true) 拆出来。