why does character controller accelerate off ledges?

Hey, so I’m using a character controller for character, but the typical movement found in the docs doesn’t allow him to change direction in air.

    /// This script moves the character controller forward 
/// and sideways based on the arrow keys.
/// It also jumps when pressing space.
/// Make sure to attach a character controller to the same game object.
/// It is recommended that you make only one call to Move or SimpleMove per frame.    

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

private var moveDirection : Vector3 = Vector3.zero;

function Update() {
    var controller : CharacterController = GetComponent(CharacterController);
    if (controller.isGrounded) {
        // We are grounded, so recalculate
        // move direction directly from axes
        moveDirection = 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
    controller.Move(moveDirection * Time.deltaTime);
}

Here is the code that allows me to change direction in air (credit:ANAMOLOUSUNDERDOG)

#pragma strict
    public var jumpSpeed:float = 8.0;
    public var wallJumpSpeed:float = 0;
    public var gravity:float = 20.0;
    public var speed:float = 6.0;
    public var jumping:boolean = false;
    private var moveDirection:Vector3 = Vector3.zero;
    private var controller:CharacterController;

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

     function Update()
    {
    
    
            moveDirection = new Vector3(Input.GetAxis("Horizontal"), moveDirection.y, Input.GetAxis("Vertical")); // make sure the old value of moveDirection.y won't get lost
            moveDirection = transform.TransformDirection(moveDirection);
         
            // don't apply speed to moveDirection.y. apply it only to x and z
            moveDirection.x *= speed;
            moveDirection.z *= speed;
           
            if (controller.isGrounded && Input.GetButton("Jump"))
            {
                    moveDirection.y = jumpSpeed;
            }

		controller.Move(moveDirection * Time.deltaTime);

}

I’m assuming it has something to do with moveDirection.y but what happens is, when walking straight off a ledge, the player accelerates downwards quickly. This does not happen when jumping, only going off ledges. What could it be?

It seems the gravity isn’t being applied - is it a typo? With gravity applied, the Y down velocity will grow indefinitely over time because it’s never being zeroed, and its effects only appear when you fall - not when on a flat surface, nor when jumping (the Y velocity is set to jumpSpeed when jumping).

Including the gravity, your code could be fixed with some changes in the if:

    ...
    if (controller.isGrounded) // when the character is grounded...
    { 
        moveDirection.y = 0;    // its Y velocity is zero...
        if (Input.GetButtonDown("Jump")) 
        {  
            moveDirection.y = jumpSpeed; // unless Jump is pressed
        }
    }
    moveDirection.y -= gravity * Time.deltaTime; // apply gravity anyway
    controller.Move(moveDirection * Time.deltaTime);
    ...