Unity: я ищу способ сравнить скорости двух игровых объектов при столкновении - PullRequest
0 голосов
/ 22 апреля 2020

Я ищу способ сравнить скорости двух игровых объектов при столкновении. Поэтому, если скорость объекта выше, чем у объекта, с которым он столкнулся, 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;
    }
}

1 Ответ

0 голосов
/ 22 апреля 2020

Если вы используете столкновение, а не триггер, то «столкновение», переданное функции OnCollisionEnter(), имеет свойство Impulse, которое дает вам представление о разнице в скорости. У него также есть GetContact(), чтобы найти, где именно произошло касание.

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

С триггерами это немного отличается. Вам необходимо рассчитать скорость предметов на точке столкновения. Проблема в том, что методы OnTriggerEnter () и OnTriggerStay () не предоставляют контактные точки.

Если ваши элементы имеют одинаковый размер, вы можете просто предположить, что точка в середине является контактной точкой, а затем вызвать c скорость на этих. Используйте для этого скорость и угловую скорость Rigidbody2D. Если ваши объекты имеют простую форму, например прямоугольные машины angular, вы можете создать собственный код для определения более полезной точки контакта.

Код в этом примере предполагает простую точку контакта в середине. из двух предметов, а затем рассчитывает скорость обоих его концов. Если вы не используете 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;

    }
}

Код, который учитывает вращение, делает его приятнее и дороже, если ваши машины выходят из-под контроля, а затем бьют кого-то, натыкаясь на него.

...