Project: Gauntlet - Current Iteration

Tuesday, December 8, 2009

Unity - Moving Platforms and You. (Triggers, Colliders, Rigidbody and the Character Controller)

Busy busy paying the rent, but here is a little snippet that you may find helpful in your Unity Endeavours.

To my surprise a Character Controller in Unity does not automatically observe moving Colliders within the game world - net result, a platform that moves around (up/down/left/right) will not support a Character Controller... you will just... fall through.

Here's my quick little solution - reasonably elegant - be wary of using CharacterController.isGrounded if you are observing a 'jump' effect - I recommend defining a global "isFalling" state that you can trigger in one of these functions.

Requirements:
A gameobject with a CharacterController
A gameobject with a Collider and a Rigidbody - tagged as "Platform", or utilizing any defining mark that you care to use - I usually use a small component that contains myriad tags and category information about an entity.


Apply these functions to a script on your your CharacterController:

   void OnTriggerEnter(Collider t)
    {
        Debug.Log("On trigger enter in " + gameObject.name);
        if (t.gameObject.tag == "Platform")
        {
            gameObject.transform.parent = t.gameObject.transform;
            Debug.Log("Parented");
        }
    }

    void OnTriggerExit(Collider t)
    {
        Debug.Log("On trigger exit in " + gameObject.name);
        if (t.gameObject.tag == "Platform")
        {
            gameObject.transform.parent = null;
            Debug.Log("Unparented");
        }
    }

Effectively, your CharacterController will move and be moved relative to the Platform while colliding (standing on), and relative to the world when not colliding.

It's really just a quickly-written piece of code for something you may or may not come across. Take it and use it in the spirit in which it was created.

1 comment:

Kimura said...

hi, i tried ur code,but it doesnt seem to work for my platform.

This is my code for my 1st person view walker. i have insert ur code here

var speed = 6.0;
var jumpSpeed = 8.0;
var gravity = 20.0;

private var moveDirection = Vector3.zero;
private var grounded : boolean = false;

function FixedUpdate() {
if (grounded) {
// We are grounded, so recalculate movedirection directly from axes
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;

if (Input.GetButton ("Jump")) {
moveDirection.y = jumpSpeed;
}
}

// Apply gravity
moveDirection.y -= gravity * Time.deltaTime;

// Move the controller
var controller : CharacterController = GetComponent(CharacterController);
var flags = controller.Move(moveDirection * Time.deltaTime);
grounded = (flags & CollisionFlags.CollidedBelow) != 0;
}

// this part not working correctly
function OnTriggerEnter(t:Collider)
{
Debug.Log("On trigger enter in " + gameObject.name);
if (t.gameObject.tag == "Platform")
{
gameObject.transform.parent = t.gameObject.transform;
Debug.Log("Parented");
}
}

function OnTriggerExit(t:Collider)
{
Debug.Log("On trigger exit in " + gameObject.name);
if (t.gameObject.tag == "Platform")
{
gameObject.transform.parent = null;
Debug.Log("Unparented");
}
}

@script RequireComponent(CharacterController)



i wonder what is wrong