- Home /
Question by
Benjamin6817 · Oct 02, 2015 at 11:49 AM ·
transformcharactercontrollerrotatelocalspaceglobalspace
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! :)
Comment
Best Answer
Answer by UsulPro · Oct 02, 2015 at 02:44 PM
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.
Thank you! I didn't expect the answer to be that simple