Why is my push rigidbody script not effected by mass?

I have this great script which allows a character controller to push rigidbodies around at a specified force. Anyone feel free to use this script for your purposes.

But it seems that the force pushing the rigidbodies does not take into account the mass of each rigidbody. So whether the rigidbody is a 2 kg cube or 1000 kg car the character controller still pushes it using the same force which obviously looks very unrealistic.

Is there a way to add the rigidbody mass into the push force calculation somehow?

I suppose it could be implemented using a tagging system; where the force is set to apply differently based on the tag of each rigidbody.

Here is the script:

// Script added to a player for it to be able to push rigidbodies around.
#pragma strict
#pragma implicit
#pragma downcast

// How hard the player can push
var LightpushPower = 0.5;
var HeavypushPower = 0.1;

// Which layers the player can push
// This is useful to make unpushable rigidbodies
var pushLayers : LayerMask = -1;

// pointer to the player so we can get values from it quickly
private var controller : CharacterController;

function Start () {
	controller = GetComponent (CharacterController);

}

function OnControllerColliderHit (hit : ControllerColliderHit) {
	if(hit.gameObject.tag == "enemy") {
	var body : Rigidbody = hit.collider.attachedRigidbody;
	// no rigidbody
	if (body == null || body.isKinematic)
		return;

	// Only push rigidbodies in the right layers
	var bodyLayerMask = 1 << body.gameObject.layer;
	if ((bodyLayerMask & pushLayers.value) == 0)
		return;
		
	// We dont want to push objects below us
	if (hit.moveDirection.y < -0.3) 
		return;
	
	// Calculate push direction from move direction, we only push objects to the sides
	// never up and down
	var pushDir = Vector3 (hit.moveDirection.x, 0, hit.moveDirection.z);
	
	body.velocity = pushDir * LightpushPower ;
	}
}

Have you looked at how your script actually manages the Rigidbody calculations? Specifically this line, the one which determines the rigidbody’s resultant force:

body.velocity = pushDir * pushPower ;

Of course, rigidbody.velocity isn’t affected by mass- only forces acting on the rigidbody are! In this, the rigidbody’s velocity is being directly modified, so of course it doesn’t take mass into account.

If you want to use actual forces, instead, use this line:

body.AddForce(pusDir * pushPower, ForceMode.Impulse);

This way, heavier bodies will move less than light ones.

Be warned- you may want to include some kind of system for limiting the resultant velocity- very light objects may get shot off into the distance otherwise!

This is what the script should look like with hit.gameObject.tag == “enemy” used. Hope it helps!!

// Script added to a player for it to be able to push rigidbodies around.
#pragma strict
#pragma implicit
#pragma downcast

// How hard the player can push
var LightpushPower = 0.5;
var HeavypushPower = 0.1;

// Which layers the player can push
// This is useful to make unpushable rigidbodies
var pushLayers : LayerMask = -1;

// pointer to the player so we can get values from it quickly
private var controller : CharacterController;

function Start () {
    controller = GetComponent (CharacterController);

}

function OnControllerColliderHit (hit : ControllerColliderHit) {
    if(hit.gameObject.tag == "enemy") {
    var body : Rigidbody = hit.collider.attachedRigidbody;
    // no rigidbody
    if (body == null || body.isKinematic)
       return;

    // Only push rigidbodies in the right layers
    var bodyLayerMask = 1 << body.gameObject.layer;
    if ((bodyLayerMask & pushLayers.value) == 0)
       return;

    // We dont want to push objects below us
    if (hit.moveDirection.y < -0.3) 
       return;

    // Calculate push direction from move direction, we only push objects to the sides
    // never up and down
    var pushDir = Vector3 (hit.moveDirection.x, 0, hit.moveDirection.z);

    body.velocity = pushDir * LightpushPower ;
    }
}