Muhammad Faizan Khan
Muhammad Faizan Khan

Reputation: 10561

Check Which object has collide with another object while scripts are same

Two Animated car object both contains rigid-body and box collider and a script with OnTriggerEnter event.

Now I want to check that which car hit to another car while both cars are running. Means if A hit to B or B hit to A as both have same script and same event then, both event becomes trigger. How to identify it who hit ???

Remember please don't recommend me to use Raycast it is expensive

For example I made two cube added box collider and rigidbody and a script that contains(or check)

void OnTriggerEnter(Collider c) {
        Debug.Log("GameObject is : " + gameObject.name + " and collider : " + c.name);

    }

Now when I triggering both object the order of trigger remain same no matter i hit A object to B or B object to A. How i will differentiate it?

Upvotes: 2

Views: 542

Answers (1)

Jerry Switalski
Jerry Switalski

Reputation: 2720

I see few ways, of which this is the easiest:

EDIT: Note - RigidBidy needs to have velocity, I mean you need to move objects with RigidBody using AddForce or any other physic based movement.

  1. Checking the velocity. Getting RigidBody of every car and checking the velocity - the one with higher velocity Vector3 is the one that hits. Note that you need to use projection here.

    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");
        }
    }
    

EDIT: Since you are not using physics to move cars, you need to calculate speed some other way

I suggest something like this:

Have a script SpeedCalculator.cs on each car.

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;
    }
}

And then instead of taking speed from RigidBody take it from SpeedCalculator:

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");
    }
}

Upvotes: 0

Related Questions