Controlling direction while jumping using CharacterController

Hi, I know this question has been asked (and solved) before, but I have had no luck with using previous solutions.

I’m fairly new to scripting in Unity, but I was doing okay until now… I just don’t understand this one thing.

I have a simple CharacterController move script and can move, turn, jump, etc. Only problem is, once I jump in a direction, I’m locked there. I have it set up to allow turning in mid-air, but I still cannot move on the Z axis.

I know about the apparent fix, removing “IsGrounded” but that has not worked for me.
Can anyone help me?

Thanks. :slight_smile:

My script:

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

private var moveDirection : Vector3 = Vector3.zero;

function Update() {
    var controller : CharacterController = GetComponent(CharacterController);
    var turn: float = Input.GetAxis("Horizontal");
    transform.Rotate(0, turn * turnSpeed * Time.deltaTime, 0);
    if (controller.isGrounded) { // only move or jump if grounded
    moveDirection = transform.forward * Input.GetAxis("Vertical") * speed;
        if (Input.GetButton ("Jump")) {
            moveDirection.y = jumpSpeed;
        }
    }
    // Apply gravity
    moveDirection.y -= gravity * Time.deltaTime;
    // Move the controller
    controller.Move(moveDirection * Time.deltaTime);
}

You must move the moveDirection calculation outside the isGrounded if - but this screws up the gravity effect, because moveDirection.y is zeroed each Update. To avoid this problem, store the vertical speed in a separate member variable, and assign it to moveDirection.y prior to move the character. Extra feature: you can store the CharacterController in another member variable (variable declared outside any function) only once, what will speed things a little. The whole thing is:

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

private var moveDirection : Vector3 = Vector3.zero;
private var vSpeed : float = 0; // keep vertical speed in a separate variable
private var controller: CharacterController; // controller reference

function Update() {
    if (!controller) controller = GetComponent(CharacterController);
    var turn: float = Input.GetAxis("Horizontal");
    transform.Rotate(0, turn * turnSpeed * Time.deltaTime, 0);
    moveDirection = transform.forward * Input.GetAxis("Vertical") * speed;
    if (controller.isGrounded) {
        vSpeed = 0; // a grounded character has zero vert speed unless...
        if (Input.GetButton ("Jump")) { // unless Jump is pressed!
            vSpeed = jumpSpeed; 
        }
    }
    // Apply gravity
    vSpeed -= gravity * Time.deltaTime;
    moveDirection.y = vSpeed; // include vertical speed
    // Move the controller
    controller.Move(moveDirection * Time.deltaTime);
}