Unity如何加额外相机避免挂载OnBecomeInvisible()的对象用cinematic camera时误销毁
问题原因
OnBecomeInvisible() 是Unity内置的生命周期函数,触发规则是游戏对象不再被场景中所有激活的Camera渲染时就会执行。过场动画体系的虚拟相机/2D相机本身属于激活的相机实例,只要它在工作时参与视锥体裁剪计算,就会影响OnBecomeInvisible()的触发判定,这是出现误销毁的核心原因。
解决方案
方案1:限定仅主相机判定可见性
放弃依赖原生的OnBecomeInvisible(),自行实现仅针对主相机的可见性检测,可通过降低检测频率控制性能消耗,示例代码如下:public Camera mainCam; // 建议提前在Inspector赋值,若只有一个主相机可通过Camera.main获取 private const float CHECK_INTERVAL = 0.5f; private float checkTimer; private void Awake() { if(mainCam == null) mainCam = Camera.main; } private void Update() { checkTimer += Time.deltaTime; if(checkTimer >= CHECK_INTERVAL) { checkTimer = 0; Plane[] frustumPlanes = GeometryUtility.CalculateFrustumPlanes(mainCam); // 2D项目替换为Collider2D,3D项目使用Collider即可 Bounds objBounds = GetComponent<Collider2D>().bounds; if(!GeometryUtility.TestPlanesAABB(frustumPlanes, objBounds)) { Destroy(gameObject); } } }该方案完全隔离了其他相机的影响,兼容性最高。
方案2:过场相机设置忽略层
将所有需要自动销毁的对象归类到同一个独立层(例如自定义层AutoDestroyObject),然后取消所有过场虚拟相机Culling Mask中该层的勾选,过场相机将不再对这类对象做裁剪计算,不会影响原生OnBecomeInvisible()的触发逻辑。
该方案改动量最小,适合过场相机数量较少的场景方案3:过场播放时暂停销毁逻辑
给自动销毁逻辑添加全局开关,过场动画播放前将开关置为false,过场结束后恢复为true,仅开关激活时执行销毁逻辑,示例代码如下:// 全局静态开关,由过场控制脚本负责修改状态 public static bool isCutscenePlaying = false; private void OnBecomeInvisible() { if(!isCutscenePlaying) { Destroy(gameObject); } }该方案适合过场逻辑清晰、播放节点可控的项目
内容的提问来源于stack exchange,提问作者Malik Nouman
相关产品推荐
相关产品推荐

