Third Person Character stuck on world axis

My character only moves up or down on the world axis, even when the camera moves around them to point in a different direction.

transform.TransformDirection should be fixing this right? Ln. 74

    public float speed = 6.0f;
    public float jumpSpeed = 8.0f;
    public float gravity = 20.0f;

    private Quaternion Rotation;

    private Vector3 moveDirection;
    private CharacterController controller;

    void Awake()
    {
        controller = GetComponent<CharacterController>() as CharacterController;
        TP_Camera.UseExistingOrCreateNewMainCamera ();
    }

    void Update()
    {   
        RotateTowardsMoveDirection ();
        ProcessMotion ();
    }

    void ProcessMotion()
    {
        if (controller.isGrounded)
        {
            moveDirection = new Vector3 (Input.GetAxis ("Horizontal"), 0, Input.GetAxis ("Vertical"));
            moveDirection *= speed;

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

        moveDirection.y -= gravity * Time.deltaTime;
        controller.Move (moveDirection * Time.deltaTime);
    }

    public void RotateTowardsMoveDirection()
    {
        if (moveDirection.x != 0 || moveDirection.z != 0)
        {
            if (moveDirection.z > 0)
            {
                if (moveDirection.x > 0)
                    Rotation = Quaternion.Euler (0, Camera.main.transform.rotation.eulerAngles.y + 45, 0);
                else if (moveDirection.x < 0)
                    Rotation = Quaternion.Euler (0, Camera.main.transform.rotation.eulerAngles.y + 305, 0);
                else
                    Rotation = Quaternion.Euler (0, Camera.main.transform.rotation.eulerAngles.y, 0);
            }

            else if (moveDirection.z < 0)
            {
                if (moveDirection.x > 0)
                    Rotation = Quaternion.Euler (0, Camera.main.transform.rotation.eulerAngles.y + 135, 0);
                else if (moveDirection.x < 0)
                    Rotation = Quaternion.Euler (0, Camera.main.transform.rotation.eulerAngles.y + 225, 0);
                else
                    Rotation = Quaternion.Euler (0, Camera.main.transform.rotation.eulerAngles.y + 180, 0);
            }

            else
            {
                if (moveDirection.x > 0)
                    Rotation = Quaternion.Euler (0, Camera.main.transform.rotation.eulerAngles.y + 90, 0);
                else if (moveDirection.x < 0)
                    Rotation = Quaternion.Euler (0, Camera.main.transform.rotation.eulerAngles.y + 270, 0);
                else
                    Rotation = transform.rotation;
            }
        }

        transform.rotation = Quaternion.Lerp (transform.rotation, Rotation, 0.25f);

        moveDirection = transform.TransformDirection (moveDirection);

        if (moveDirection.magnitude > 1)
            moveDirection = Vector3.Normalize (moveDirection);
    }

}

transform.TransformDirection is generally used to rotate a movement value (like in your processMotion method) from a local to world space.

So if you press forward, you want to transform the forward direction of the keys to that of the forward direction of the character.

I am fairly confused at the whole RotateTowardsMoveDirection method, with all of the arbitrary numbers.

I did this script a while back just to play with, it may help you a bit.

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(CharacterController))]
public class SimpleController : MonoBehaviour
{
    Camera camera; // the camera....
    float x, y; // handles mouse capture
    public float speed = 8; // for movement
    // for scrolling....
    public float minThirdPersonDistance = 0;
    public float maxThirdPersonDistance = 20;
    float thirdPersonDistance = 0;


    // Use this for initialization
    void Start()
    {
        // set the camera up
        camera = Camera.main;
        if (camera == null) camera = Camera.allCameras[0];

        // capture the camera's current euler angle.
        var euler = camera.transform.eulerAngles;
        x = euler.x;
        y = euler.y;
    }

    void Update()
    {
        // capture the mouse for the view
        x -= Input.GetAxis("Mouse Y") * 20;
        y += Input.GetAxis("Mouse X") * 20;

        // clamp the X angle so that we dont look upside down.
        x = ClampAngle(x, -60, 60);
        camera.transform.position = transform.position + Vector3.up * 0.5f;
        camera.transform.eulerAngles = new Vector3(x, y, 0);

        // keep the camera looking at the mouse based angles
        var lookAt = camera.transform.TransformPoint(Vector3.forward);
        lookAt.y = transform.position.y;
        transform.LookAt(lookAt);

        // handle movement
        var move = Vector3.zero;
        move.z = Input.GetAxis("Vertical");
        move.x = Input.GetAxis("Horizontal");
        if (move.sqrMagnitude > 1) move.Normalize();
        move *= speed;
        move = transform.TransformDirection(move);
        var controller = GetComponent<CharacterController>();
        controller.SimpleMove(move);

        // handle the third person camera
        thirdPersonDistance -= Input.GetAxis("Mouse ScrollWheel") * 20;
        thirdPersonDistance = Mathf.Clamp(thirdPersonDistance, minThirdPersonDistance, maxThirdPersonDistance);
        camera.transform.Translate(-Vector3.forward * thirdPersonDistance, Space.Self);
    }

    // clamp the current angle
    float ClampAngle(float angle, float min, float max)
    {
        angle %= 360;
        if (angle > 180) angle -= 360;
        return Mathf.Clamp(angle, min, max);
    }
}

RotateTowardsMoveDirection() is just checking to see if the character is moving in any way along the x and z axis, then based on the inputs adds a value with the main cameras y rotation (which is always 0) to a Quaterion called Rotation’s y axis. Then it rotates the player using Rotation with some lerping for smoothness.

I thought transform.TransformDirection should then allow it to move freely based on where the camera is around it.

Would there be a way to make the character move based on the camera? Like to the cameras left, right, forward and back?

transform.TransformDirection calculates a direction based off the person…

camera.transform.TransformDirection calculates a direction based off the camera. (Note: this is off the camera, so the forward direction of a down pointing camera will still point down)

Check my code about line 37-43. I move the camera to the player’s position and then set the player’s “look” based off of that. I simply reposition the camera back afterward.