C# 检查脚本相同时哪个对象与另一个对象发生碰撞

C# 检查脚本相同时哪个对象与另一个对象发生碰撞,c#,unity3d,C#,Unity3d,两个已设置动画的汽车对象都包含刚体和框碰撞器,以及带有OnTriggerEnter事件的脚本 现在我想检查两辆车都在行驶时,哪辆车撞到了另一辆车。意味着如果A命中B或B命中A,因为两者都有相同的脚本和相同的事件,那么这两个事件都成为触发器。如何识别是谁打的 记住,请不要建议我使用Raycast,因为它很昂贵 例如,我制作了两个立方体添加框碰撞器和刚体,以及一个包含(或检查)的脚本 现在,当我触发两个对象时,无论我将一个对象击中B还是将B对象击中A,触发顺序都保持不变。我将如何区分它?我看到了几种

两个已设置动画的汽车对象都包含刚体框碰撞器,以及带有OnTriggerEnter事件的脚本

现在我想检查两辆车都在行驶时,哪辆车撞到了另一辆车。意味着如果A命中B或B命中A,因为两者都有相同的脚本和相同的事件,那么这两个事件都成为触发器。如何识别是谁打的

记住,请不要建议我使用Raycast,因为它很昂贵

例如,我制作了两个立方体添加框碰撞器和刚体,以及一个包含(或检查)的脚本


现在,当我触发两个对象时,无论我将一个对象击中B还是将B对象击中A,触发顺序都保持不变。我将如何区分它?

我看到了几种方法,其中最简单的是:

编辑:注意-
刚体
需要有速度,我的意思是你需要使用
刚体
移动对象,使用
AddForce
或任何其他基于物理的移动。

  • 检查速度。 获取每辆车的
    刚体
    ,并检查
    速度
    ——速度更高的
    矢量3
    就是命中的那辆。请注意,这里需要使用投影

    void OnTriggerEnter(Collider c) 
    {
        Debug.Log("GameObject is : " + gameObject.name + " and collider : " + c.name);
    
        Vector3 directionB = this.transform.position - c.transform.position;
        Vector3 directionA = c.transform.position - this.transform.position;
    
        Vector3 rawVelocityA = this.GetComponent<Rigidbody> ().velocity;
        Vector3 rawVelocityB = c.GetComponent<Rigidbody> ().velocity;
    
        Vector3 realSpeedA = Vector3.Project (rawVelocityA, directionA);
        Vector3 realSpeedB = Vector3.Project (rawVelocityB, directionB);
    
        if (realSpeedA.magnitude > realSpeedB.magnitude) 
        {
            Debug.Log ("A hit B");
        }
        else if (realSpeedB.magnitude > realSpeedA.magnitude) 
        {
            Debug.Log ("B hit A");
        }
        else
        {
            Debug.Log ("A hit B and B hit A");
        }
    }
    
    然后从
    刚体
    获取速度,而不是从
    速度计算器
    获取速度:

    void OnTriggerEnter(Collider c) 
    {
        Debug.Log("GameObject is : " + gameObject.name + " and collider : " + c.name);
    
        Vector3 directionB = this.transform.position - c.transform.position;
        Vector3 directionA = c.transform.position - this.transform.position;
    
        Vector3 rawVelocityA = this.GetComponent<SpeedCalculator> ().Velocity;
        Vector3 rawVelocityB = c.GetComponent<SpeedCalculator> ().Velocity;
    
        Vector3 realSpeedA = Vector3.Project (rawVelocityA, directionA);
        Vector3 realSpeedB = Vector3.Project (rawVelocityB, directionB);
    
        if (realSpeedA.magnitude > realSpeedB.magnitude) 
        {
            Debug.Log ("A hit B");
        }
        else if (realSpeedB.magnitude > realSpeedA.magnitude) 
        {
            Debug.Log ("B hit A");
        }
        else
        {
            Debug.Log ("A hit B and B hit A");
        }
    }
    
    无效对撞机(对撞机c)
    {
    Log(“GameObject是:“+GameObject.name+”和collider:“+c.name”);
    向量3方向b=this.transform.position-c.transform.position;
    向量3方向a=c.transform.position-this.transform.position;
    Vector3 rawVelocityA=this.GetComponent().Velocity;
    Vector3 rawVelocityB=c.GetComponent().Velocity;
    Vector3 realSpeedA=Vector3.Project(rawVelocityA,directionA);
    Vector3 realSpeedB=Vector3.Project(rawVelocityB,directionB);
    if(realSpeedA.magnitude>realSpeedB.magnitude)
    {
    Log(“A命中B”);
    }
    否则如果(realSpeedB.magnitude>realSpeedA.magnitude)
    {
    Log(“B命中A”);
    }
    其他的
    {
    Log(“A命中B和B命中A”);
    }
    }
    
    难以设想的事情。我建议发布您尝试的内容并解释您阻止的位置。添加了一些详细信息的代码片段检查对象的速度(假设命中的对象速度更快)或使用更多碰撞器(您只能使用前面的碰撞器)更快的是我没有得到这一点,而对于第二个选项,它可能是冗长但可行的解决方案@ukaszMotyczka,但第二个解决方案的问题是,我必须在一个汽车对象上添加四个碰撞器和四个刚体。性能缺陷不是吗?解决方案不起作用,我在两个立方体上测试它,它的场景视图总是显示一个命中B和一个命中A,这让我感到惊讶,因为我不知道这里会出什么问题-为什么两个realSpeed向量的长度相等。你确定刚体有速度吗?我想他们没有。我将编辑答案。没有速度,正如我告诉你的,我正在通过移动方向箭头在场景视图中检查它。我移动对象只是为了检查代码。好的,那么如何移动汽车?改变刚体还是直接变换?汽车动画和循环动画都在样条曲线上一点移动,会发生碰撞
    public class SpeedCalculator : MonoBehaviour 
    {
        public float Velocity
        {
            get
            {
                return velocity;
            }
        }
        private float velocity;
    
        private Vector3 lastPosition;
    
        void Awake()
        {
            lastPosition = transform.position;
        }
    
        void Update()
        {
            velocity = transform.position - lastPosition;
            lastPosition = transform.position;
        }
    }
    
    void OnTriggerEnter(Collider c) 
    {
        Debug.Log("GameObject is : " + gameObject.name + " and collider : " + c.name);
    
        Vector3 directionB = this.transform.position - c.transform.position;
        Vector3 directionA = c.transform.position - this.transform.position;
    
        Vector3 rawVelocityA = this.GetComponent<SpeedCalculator> ().Velocity;
        Vector3 rawVelocityB = c.GetComponent<SpeedCalculator> ().Velocity;
    
        Vector3 realSpeedA = Vector3.Project (rawVelocityA, directionA);
        Vector3 realSpeedB = Vector3.Project (rawVelocityB, directionB);
    
        if (realSpeedA.magnitude > realSpeedB.magnitude) 
        {
            Debug.Log ("A hit B");
        }
        else if (realSpeedB.magnitude > realSpeedA.magnitude) 
        {
            Debug.Log ("B hit A");
        }
        else
        {
            Debug.Log ("A hit B and B hit A");
        }
    }