Unity中Inspector显示碰撞布尔值为true,但代码判断返回false
问题:Unity触发检测时机导致布尔值读取异常
问题场景
我正在开发Unity脚本,用于检测当前平面周围是否存在其他平面。通过实例化4个挂载了如下脚本的立方体碰撞体实现:
public bool collided = false; public GameObject collidedPlane; void OnTriggerEnter(Collider coll){ if(coll.gameObject.layer == 3){ // 3为目标碰撞层 collided = true; collidedPlane = coll.gameObject; } } public bool isCollided(){ if(collided) return true; else return false; }
在Inspector中查看时,collided布尔值显示为true,符合预期。但在代码中直接读取该布尔值或调用isCollided()方法时,返回结果均为false。
检测代码示例(共4处类似逻辑):
currentlyInstantiated = InstantiationPlace(-20, 0, colliderCheck); //实例化对象 if(currentlyInstantiated.GetComponent<CollidedWithWho>().isCollided()) //检测collided值 //执行对应操作
其中InstantiationPlace函数定义:
GameObject InstantiationPlace(int x, int z, GameObject theObject) { return Instantiate(theObject, currentRoomPosition + new Vector3(x, 0, z), Quaternion.identity); }
colliderCheck是带有上述脚本、碰撞体及刚体的预制体。怀疑是代码检测时机早于OnTriggerEnter执行导致的问题,求解决办法。
解决方案
延迟检测时机:Unity的物理回调(如
OnTriggerEnter)在**物理更新阶段(FixedUpdate)**执行,而实例化代码通常在普通Update或Start中运行,实例化后立刻读取肯定拿不到触发结果。可以用两种方式延迟:- 用协程等待一帧:
currentlyInstantiated = InstantiationPlace(-20, 0, colliderCheck); StartCoroutine(CheckCollisionAfterFrame(currentlyInstantiated)); IEnumerator CheckCollisionAfterFrame(GameObject obj) { // 等待一帧,让物理系统完成触发检测 yield return null; if(obj.GetComponent<CollidedWithWho>().isCollided()) { // 执行对应操作 } // 更稳妥的方式是等待物理帧:yield return new WaitForFixedUpdate(); } - 在FixedUpdate中统一检测:把实例化的检测对象存入列表,在
FixedUpdate里遍历列表检查碰撞状态,处理完成后移除或销毁对象。
- 用协程等待一帧:
主动触发检测,替代被动回调:如果不想依赖物理帧的时机,可以修改检测脚本,添加手动检测方法,实例化后直接调用:
// 修改CollidedWithWho脚本,添加主动检测方法 public bool CheckCollisionManually() { // 用OverlapBox检测当前位置的目标层物体 Collider[] hits = Physics.OverlapBox(transform.position, GetComponent<Collider>().bounds.extents, Quaternion.identity, 1 << 3); if(hits.Length > 0) { collided = true; collidedPlane = hits[0].gameObject; return true; } return false; }调用示例:
currentlyInstantiated = InstantiationPlace(-20, 0, colliderCheck); if(currentlyInstantiated.GetComponent<CollidedWithWho>().CheckCollisionManually()) { // 执行对应操作 }优化对象生命周期:这些检测立方体如果只是一次性使用,处理完碰撞逻辑后建议立刻销毁,避免不必要的内存占用。
内容的提问来源于stack exchange,提问作者Cozmax
相关产品推荐
相关产品推荐

