You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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中运行,实例化后立刻读取肯定拿不到触发结果。可以用两种方式延迟:

    1. 用协程等待一帧:
      currentlyInstantiated = InstantiationPlace(-20, 0, colliderCheck);
      StartCoroutine(CheckCollisionAfterFrame(currentlyInstantiated));
      
      IEnumerator CheckCollisionAfterFrame(GameObject obj)
      {
          // 等待一帧,让物理系统完成触发检测
          yield return null;
          if(obj.GetComponent<CollidedWithWho>().isCollided())
          {
              // 执行对应操作
          }
          // 更稳妥的方式是等待物理帧:yield return new WaitForFixedUpdate();
      }
      
    2. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 23:30:21