You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity进化模拟器:OnTriggerEnter未触发碰撞却销毁物体问题求助

问题分析与解决方案

嘿,我一眼就看出问题所在了——你在Update()方法里手动调用了OnTriggerEnter(),完全绕过了Unity的碰撞检测系统,这就导致不管生物有没有真的碰到食物,食物都会被直接销毁!

问题根源

你的Update()方法里这段代码是罪魁祸首:

void Update() {
    Rigidbody[] allRigidBodies = (Rigidbody[])FindObjectsOfType(typeof(Rigidbody));
    foreach (Rigidbody body in allRigidBodies) {
        if (body.gameObject.layer == 10) {
            OnTriggerEnter(body.gameObject.GetComponent<CapsuleCollider>());
        }
    }
}

这段代码在每一帧都会遍历所有带Rigidbody的物体,只要发现layer是10的物体,就直接调用OnTriggerEnter()方法销毁食物——完全不管两者有没有实际触发碰撞。

修复步骤

  1. 删掉Update里的所有代码
    Unity的OnTriggerEnter()是由引擎自动触发的,不需要你手动调用。只要碰撞条件满足,引擎会自动执行这个方法。

  2. 确保碰撞设置正确
    要让触发器正常工作,你需要满足以下条件:

    • 食物的CapsuleCollider必须勾选IsTrigger选项
    • 生物对象必须带有Rigidbody组件(触发器需要至少一个参与碰撞的物体有Rigidbody)
    • 可以在OnTriggerEnter()里加个判断,确保只有生物触发时才销毁食物:
      private void OnTriggerEnter(Collider creature) {
          // 检查触发的物体是否是生物(通过layer判断)
          if (creature.gameObject.layer == 10) {
              Destroy(gameObject); // 直接销毁当前挂载脚本的物体,无需额外引用
          }
      }
      
  3. 优化冗余代码
    你的脚本里FoodGOFoodRB是多余的,直接用gameObjectGetComponent<Rigidbody>()即可,简化后的完整脚本如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FoodEat : MonoBehaviour {
    private void OnTriggerEnter(Collider creature) {
        // 只在生物(layer 10)触发时销毁食物
        if (creature.gameObject.layer == 10) {
            Destroy(gameObject);
        }
    }

    void Start() {
        // 如果需要用到Rigidbody,直接在这里获取即可,无需额外赋值给字段
        // Rigidbody foodRB = GetComponent<Rigidbody>();
    }
}

额外提示

  • 如果你想用tag来区分生物和其他物体,也可以把判断改成creature.CompareTag("Creature"),记得给生物对象设置对应的tag
  • 确保食物和生物的碰撞体没有被禁用,且两者的位置/大小设置合理,避免出现误触发

内容的提问来源于stack exchange,提问作者Vojtěch Vach

火山引擎 最新活动