CharacterControllers and Transform.Rotate

I have a very simple question. I have a simple script. It uses the A and D keys to rotate the player and the W and S keys to move forward and back. When I press A or D to rotate the CharacterController ignores the movement as if it’s movement on a global axis? How can I fix this?

Here is the code if it will help:

using UnityEngine;
using System.Collections;

public enum MovementState
{
	standing = 0,
	walking = 1,
	running = 2,
	sprinting = 3,
	jumping = 4
}

[RequireComponent (typeof(CharacterController))]
public class MovementController : MonoBehaviour
{
	[System.Serializable]
	public class WalkSpeedProps
	{
		public float forwardSpeed = 3.0f;
		public float backwardSpeed = 2.5f;
		public float strafeSpeed = 2.75f;
	}

	[System.Serializable]
	public class RunSpeedProps
	{
		public float forwardSpeed = 4.0f;
		public float backwardSpeed = 3.0f;
		public float strafeSpeed = 3.75f;
	}

	[System.Serializable]
	public class SprintSpeedProps
	{
		public float forwardSpeed = 6.0f;
		public float backwardSpeed = 4.5f;
		public float strafeSpeed = 5.0f;
	}

	public MovementState mvState = MovementState.standing;
	public WalkSpeedProps WalkSpeed;
	public RunSpeedProps RunSpeed;
	public SprintSpeedProps SprintSpeed;
	public float rotationSpeed = 3.0f;
	public float airControl = 4.0f;
	public float runThreshold = 0.5f;
	public float jumpForce = 8.0f;
	public float gravity = 20.0f;

	private CharacterController player;
	private float horizontal, vertical, speed, strafeSpeed;
	private Vector3 moveDirection = Vector3.zero;
	private bool movingForward = true;

	public void Start ()
	{
		player = GetComponent<CharacterController> ();

		speed = SprintSpeed.forwardSpeed;
		strafeSpeed = SprintSpeed.strafeSpeed;

		if (!player)
			Debug.Log ("Please attach a CharacterController to the " + gameObject.name + " gameobject.");
	}

	public void Update ()
	{
		if (!player)
			return;

		horizontal = Input.GetAxis ("Horizontal");
		vertical = Input.GetAxis ("Vertical");

		// Figure out the players movement state
		if (!player.isGrounded)
			mvState = MovementState.jumping;
		else {
			if (vertical == 0 && horizontal == 0)
				mvState = MovementState.standing;
			else if (Input.GetButton ("Sprint"))
				mvState = MovementState.sprinting;
			else if (Mathf.Abs (vertical) < runThreshold && Mathf.Abs (horizontal) < runThreshold)
				mvState = MovementState.walking;
			else if (Mathf.Abs (vertical) > runThreshold || Mathf.Abs (horizontal) > runThreshold)
				mvState = MovementState.running;
		}

		if (vertical < 0)
			movingForward = false;
		else
			movingForward = true;

		if (mvState == MovementState.walking) {
			speed = movingForward ? WalkSpeed.forwardSpeed : WalkSpeed.forwardSpeed;
			strafeSpeed = WalkSpeed.strafeSpeed;
		} else if (mvState == MovementState.running) {
			speed = movingForward ? RunSpeed.forwardSpeed : RunSpeed.forwardSpeed;
			strafeSpeed = RunSpeed.strafeSpeed;
		} else if (mvState == MovementState.sprinting) {
			speed = movingForward ? SprintSpeed.forwardSpeed : SprintSpeed.forwardSpeed;
			strafeSpeed = SprintSpeed.strafeSpeed;
		} else if (mvState == MovementState.jumping) {
			speed = airControl;
			strafeSpeed = airControl;
		}

		if (Input.GetButton ("Jump") && player.isGrounded)
			moveDirection.y = jumpForce;

		if (Input.GetMouseButton (1))
			moveDirection.x = horizontal * strafeSpeed;
		else
			transform.Rotate (0, horizontal * rotationSpeed, 0);

		moveDirection.z = vertical * speed;

		moveDirection = transform.TransformDirection (moveDirection);

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

		Debug.Log (mvState);
	}
}

Thanks, in advanced! :slight_smile:

Hi, @Benjamin6817! You can fix it by reseting moveDirection before assigning new values from Input. Just add string " moveDirection.Set(0, 0, 0); " in the beginning of Update(). It happens because you rotating this vector every frame so it constantly summarizing local and world coordinates.