首页 > 解决方案 > Unity:我正在寻找一种方法来比较两个游戏对象在碰撞时的速度

问题描述

我正在寻找一种方法来比较两个游戏对象在碰撞时的速度。因此,如果对象的速度比它与它碰撞的对象快,则 ApplysBreak。但是,当我尝试访问每个游戏对象的速度变量时,我得到一个空引用。

那么我想做的是让汽车在路上行驶。这些汽车在前部有一个触发器,在汽车后部有一个碰撞箱。我想要发生的是当触发器击中碰撞箱时,它比较碰撞中两辆车的速度变量,即使后面的汽车减速或等于前面汽车的速度。但是,我遇到的麻烦是参考两辆车的速度并比较它们。这是因为它们都是使用相同脚本的预制件。我正在学习这意味着我只是引用相同的脚本,而不是单个汽车的实际值。

private void OnTriggerStay2D(Collider2D collision)
{
    Debug.Log("TriggerStay");

    Traffic Col_speed = collision.gameObject.GetComponent<Traffic>();

    if (speed > Col_speed.speed)
    {
        Accelerate = false;
        ApplyBreak = true;
    }
    else if (speed< Col_speed.speed)
    {
        Accelerate = false;
        ApplyBreak = false;
        speed = Col_speed.speed;
    }
}

标签: c#unity3dcomparecollision-detection

解决方案


如果您使用碰撞而不是触发器,则传递给OnCollisionEnter()函数的“碰撞”具有一个属性Impulse,它可以让您了解速度的差异。它还可以GetContact()找到确切触摸的位置。

https://docs.unity3d.com/ScriptReference/Collision.html

使用触发器,它有点不同。您需要计算碰撞点上物品的速度。麻烦的是, OnTriggerEnter() 和 OnTriggerStay() 方法不提供接触点。

如果您的项目大小相似,您可以简单地假设中间的点是接触点,然后计算这些点的速度。使用 Rigidbody2D 的速度和 angularVelocity 来执行此操作。如果您的对象具有简单的形状,例如矩形汽车,您可能会编写一些自己的代码来找出更有用的接触点。

本示例中的代码假设两个项目中间有一个简单的接触点,然后计算它两端的速度。如果您不在同一个对象上使用 Rigidbody2D,而是在某个父对象中使用,您可能需要稍微更改一下。从父级获取刚体时,请注意使用具有刚体的同一游戏对象的 transform.position,而不是具有碰撞器的游戏对象!

using UnityEngine;

public class TriggerHitSpeed : MonoBehaviour
{
    public Vector3 hit_v1;
    public Vector3 hit_v2;
    private Rigidbody2D rgb;

    private void Start()
    {
        rgb = GetComponent<Rigidbody2D>();
        if(rgb==null)
            Destroy(this);
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        Vector3 hitpoint;

        // unlike OnCollisionEnter2D(), trigger functions don't get a contact point
        // simply assume middle of centers. For a CollisionEnter, can use the contact point from the collision.
        hitpoint = (collision.transform.position+transform.position)*0.5f;
        // speed of self at hitpoint
        Vector3 rotspeed;
        Vector3 v1,v2;
        Vector2 speed;
        if(rgb!=null)
        {
            rotspeed = Vector3.forward * rgb.angularVelocity*Mathf.Deg2Rad;  // for 3D object, use angularVelocity directly.
            speed = rgb.velocity;
            v1 = Vector3.Cross( rotspeed , hitpoint-transform.position );
            v1 += new Vector3(speed.x,speed.y,0f);
        }else
            v1 = Vector3.zero;
        // speed of other at hitpoint
        if(collision.attachedRigidbody!=null)
        {
            rotspeed = Vector3.forward * collision.attachedRigidbody.angularVelocity*Mathf.Deg2Rad;// for 3D object, use     angularVelocity directly.
            speed = collision.attachedRigidbody.velocity;
            v2 = Vector3.Cross( rotspeed , hitpoint-collision.transform.position );
            v2 += new Vector3(speed.x,speed.y,0f);
        }else
            v2 = Vector3.zero;

        // can now look at the difference and do something with it.
        //   v2-v1;
        // [...]
        hit_v1 = v1;
        hit_v2 = v2;

    }
}

考虑旋转的代码使它更好,更昂贵,以防您的汽车失去控制然后撞到某人,将他撞到一边。


推荐阅读