Character Contoler interact with rigidbodies

Hi, I just want to know how to make the first person controller interact with rigidbodies. For example, if i have a stack of cylenders, i want to knock them over when i walk into them, or if i have a cube, i want to push it. How do i do that? ive tried making the character a rigidbody, adding a rigidbody cube to the character, nothing seems to work. Ant ideas?

have you set colliders up on the objects you wish to interact with…?

yes, all the objects have colliders. Maybe the Character controller dosent?

give the charector controller a rigid body and that should be it

i tried, like i said, and it dident work. When i have a chance, ill be sure everything has a collider. wait, accually, i think i tried to ad a collider component to the CC, but then that would replace the CC component.

There is an example of this in the 2D GamePlay Tutorial:

Rune

Ok, I have this script, applied to the Character Controller named FPSPlayer:

// Script added to a player for it to be able to push rigidbodies around.

// How hard the player can push
var pushPower = 0.5;

// 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 : FPSPlayer;

function Start () {
	controller = GetComponent (FPSPlayer);
}

function OnControllerColliderHit (hit : ControllerColliderHit) {
	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);
	
	// push with move speed but never more than walkspeed
	body.velocity = pushDir * pushPower * Mathf.Min (CharacterController.GetSpeed (), CharacterController.movement.walkSpeed);
}

But the console says:‘The name FPSPlayer does not denote a valid type’ What does that mean and how do I fix it?

I notice the “controller” var is not used in the script… :?
If you want to make a pointer to the player use a public var and assign it in the Inspector (this is the easier way to do it).

Ok, I changed the code, but the console says:

GetSpeed’ is not a member of ‘UnityEngine.CharacterController’
"movement’is not a member of ‘UnityEngine.CharacterController’
These are at the bottom of the script:

// Script added to a player for it to be able to push rigidbodies around.

// How hard the player can push
var pushPower = 0.5;

// 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
var controller : CharacterController;

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

function OnControllerColliderHit (hit : ControllerColliderHit) {
	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);
	
	// push with move speed but never more than walkspeed
	body.velocity = pushDir * pushPower * Mathf.Min (CharacterController.GetSpeed (), CharacterController.movement.walkSpeed);
}

What will i need to change?

You are trying to access custom functions and variables (GetSpeed(),movement…) without a correct reference in your script.
You will need to assign the correct gameobject to the controller var in the Inspector and then:

Instead of this:

CharacterController.GetSpeed ();

CharacterController.movement.walkSpeed);

Try this:

controller.GetSpeed ();
controller.movement.walkSpeed);

Still no go. What should I do?

anyone?

Still not working… suggestions?

Well, in response to the last suggestion, you replied “Still no go”. I guess your script is still not working, but it is difficult to see now where you are up to with this. Can you post the current state of your code and whatever error messages or problems you are getting?

yep, not working. can YOU make a script to push rigid bodies? I have no idea what to write…

http://forum.unity3d.com/viewtopic.php?t=32060&highlight=push+rigidbody

YEA! IT WORKS! but 2 problems:
I need it to only push rigidbodies with a ceratin mass.
It always pushes up, never along just the x and z axis…
but that second one isent that important. however, the mass of the objects is… Suggestions…

YEA figured out how to make it not turn like that. ‘freeze rotation’. cool. I think, in my game, only big crates will have that, to simulate the larger mass. speaking of mass, i still need to be able to push only certain masses! Thanks, your a great helper…

Ok, new problem has come up…
Im wondering how to push rigidbodies that are a certain mass. However, the scripting reference states that mass is used to change the mass, not define it. What about layers? Built in layers only work with lights and such, but theres tags, and theres layers via script. But, how would I write a script to ignore rigidbodies in those layers? :?

Resurrecting this really old post…
I came across the same problem today, and fixed the code in this post to run on c# / modern unity, I hope it helps someone:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectPusher : MonoBehaviour
{
    [SerializeField]
    float pushPower = 0.5f;
    //int pushLayers = -1;

    private CharacterController _characterController;


    private void Start()
    {
        _characterController = GetComponent<CharacterController>();
    }

    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
       
        var body = 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) == 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 = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);

        // push with move speed but never more than walkspeed
        body.velocity = pushDir * pushPower * _characterController.velocity.magnitude;
    }
}
1 Like