Always Get Same Physics Collision Rebound Force

I was working on a 3d car war game, and I was moving my cars through velocity using the following code:

appliedSpeed += Time.fixedDeltaTime * 8f;
        appliedSpeed = Mathf.Min (appliedSpeed, speed);
        myRigidbody.velocity = transform.forward * appliedSpeed;

At collision time, I was giving backward force using the following code:

private void ApplyReboundForce (Collision other)
    {
        Vector3 reboundDirection = other.contacts [0].point - transform.position;
        reboundDirection = -reboundDirection.normalized;
//        myRigidbody.AddForce (reboundDirection * 7f, ForceMode.Impulse);
        myRigidbody.AddForce (reboundDirection * 180f, ForceMode.Force);
    }

But at present, I was getting a collision response force dynamically. Sometimes it was a higher force and sometimes it was lower force based on physics calculation.
I want collision response force always same.

Here is the reference game for collision response force:

I have already made all physics property of all cars same like physics material, rigidbody properties values etc… then also getting different collision response on each collision.
Please give me some suggestion to achieve something similar.

Hi @siddharth3322 ,

I just saw the video and your script , the force can be different in case of each collision, because you are using collision by points, thus the value of variable can “reboundDirection” can be different in case of objects with different sizes and positions.

I made the following changes to your code , see if it best suits you :

using UnityEngine;

public class speed : MonoBehaviour {

    public Rigidbody thisRB;
    float appliedSpeed = 0.0f;
    public float theSpeed = 1.0f;

    public float impactForce = 15.0f;


    // Update is called once per frame
    void FixedUpdate () {
        appliedSpeed += Time.deltaTime * 8.0f;
        appliedSpeed = Mathf.Min(appliedSpeed, theSpeed);
        thisRB.velocity = (transform.forward * appliedSpeed);
    }

    private void OnCollisionEnter(Collision collision)
    {
        Vector3 reboundDirection = Vector3.Normalize(transform.position - collision.transform.position);
        reboundDirection.y = 0.0f;

        Debug.Log("Rebound Force is " + reboundDirection);
        thisRB.AddForce(reboundDirection * impactForce, ForceMode.Force);
        appliedSpeed = 0.0f;
    }
}

I would suggest multiplying the impact force by the mass of the colliding rigid body, if you are increasing mass of the object , as per its size , as seen in the video.

Also freeze unnecessary rotations and position in Y - axis.

Good Luck !

1 Like

@Magnas_94 thank you for your reply and I carefully applied whichever points you have suggested.
Let me share overall experience with you.

 // Update is called once per frame
    void FixedUpdate () {
        appliedSpeed += Time.deltaTime * 8.0f;
        appliedSpeed = Mathf.Min(appliedSpeed, theSpeed);
        thisRB.velocity = (transform.forward * appliedSpeed);
    }

This code, I can’t able to put directly in FixedUpdate method otherwise it directly started controlling car movement.
So car background force gets stopped directly. I have modified the code like this way:

 // Update is called once per frame
    void FixedUpdate()
    {
        //        if (brakePlayerCar && myRigidbody.velocity.magnitude > 3f) {
        //            return;
        //        } else
        //            brakePlayerCar = false;

        elapsedEngineStartWaiting += Time.deltaTime;
        if (elapsedEngineStartWaiting < 0.7f)
            return;

        // Move the player forward
        appliedSpeed += Time.deltaTime * 10f;
        appliedSpeed = Mathf.Min(appliedSpeed, speed);
        myRigidbody.velocity = transform.forward * appliedSpeed;
}

Overall added waiting time to start car engine again.

Here you have the code that applied on collision with other cars:

    void OnCollisionEnter(Collision other)
    {
        if (other.gameObject.CompareTag(GameConstants.TAG_ENEMY))
        {
            //appliedSpeed = speed * 0.5f;
            elapsedEngineStartWaiting = 0f;
            ApplyReboundForce(other);
        }
    }

    private void ApplyReboundForce(Collision other)
    {
        Vector3 reboundDirection = Vector3.Normalize(transform.position - other.transform.position);
        reboundDirection.y = 0f;

        //Vector3 reboundDirection = other.contacts [0].point - transform.position;
        //reboundDirection = -reboundDirection.normalized;
        //myRigidbody.AddForce(reboundDirection * 5f, ForceMode.Impulse);
        myRigidbody.AddForce(reboundDirection * 180f, ForceMode.Force);
    }

Here is the overall car configuration:

Still, I can’t able to get the same collision response always, it continuously dynamic.
Whether I require to control rebound force manually?
Please give me some more suggestions into this so I can get above video kind of output.

1 Like

Hi @siddharth3322 ,

I got the exact setup you needed for your game , our code had 1 major issue :

We were adding to the velocity to move the car forward, but we were also adding a force to push our cars back , that was causing that jittery throwback of the car , I made some changes to the way our car catches speed, also I changed the way forces are added , so that it always remains constant.

using UnityEngine;

public class speed : MonoBehaviour {

    public Rigidbody thisRB;
    float appliedSpeed = 0.0f;
    public float theSpeed = 1.0f;

    public float impactForce = 15.0f;


    // Update is called once per frame
    void FixedUpdate () {
        appliedSpeed += Time.deltaTime * 8.0f;
        appliedSpeed = Mathf.Min(appliedSpeed, theSpeed);
        // thisRB.velocity = (transform.forward * appliedSpeed);
        if(thisRB.velocity.z < theSpeed)
            thisRB.AddForce(transform.forward * appliedSpeed, ForceMode.VelocityChange);
    }

    private void OnCollisionEnter(Collision collision)
    {
          Vector3 reboundDirection = -transform.forward;
          // I have applied force in direction of our car's back, since impacts were back pushed , mostly
          // CHANGE THIS BY collision.transform.forward , if you want our car to bounce back in the direction of opponent's forward!
    
        thisRB.AddForce(reboundDirection * impactForce, ForceMode.Impulse);
        appliedSpeed = 0.0f;
    }
}

Also , I got a similar result as your video , bu putting these values :

Rigidbody :
Mass : 1

Speed Script :
The Speed = 15
Impact Force = 40.

Hope it helps !! :slight_smile:

1 Like

I have given you a personal message with my project’s more details included in it. So please check this and reply back to me.