
Question:
I have made a script with movement, that finally works as i want it to, except one thing... I want it to be a first person game, but the way the movement works now, is on the global axis, which means that W is always torwards one specific direction, no matter what direction my camera is turning... How do i fix this? i want the movement to stay how it is, but with the W key to always be forward depending on the way the camera or player is looking.
Please let me know how my script would look edited, or atleast what part i have to change.
I would also like to add that i would love to be able to do a wall jump, but i am not sure how to add that behavior.
Here is my movement script:
public class MovementScript : MonoBehaviour {
public float speed;
public float jumpforce;
public float gravity = 25;
private Vector3 moveVector;
private Vector3 lastMove;
private float verticalVelocity;
private CharacterController controller;
// Use this for initialization
void Start () {
controller = GetComponent<CharacterController> ();
//Låser og gemmer musen
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update () {
//Låser musen op
if (Input.GetKeyDown ("escape"))
Cursor.lockState = CursorLockMode.None;
moveVector = Vector3.zero;
moveVector.x = Input.GetAxis("Horizontal");
moveVector.z = Input.GetAxis("Vertical");
if (controller.isGrounded) {
verticalVelocity = -1;
if (Input.GetButton("Jump")) {
verticalVelocity = jumpforce;
}
} else {
verticalVelocity -= gravity * Time.deltaTime;
moveVector = lastMove;
}
moveVector.y = 0;
moveVector.Normalize ();
moveVector *= speed;
moveVector.y = verticalVelocity;
controller.Move (moveVector * Time.deltaTime);
lastMove = moveVector;
}
}
Answer1:You need to go from local to world space:
for example when you want to move on the x-axis regarding the player's orientation, the local vector is (1, 0, 0), which you get from your input axis, but the CharacterController
need a world based direction (see <a href="https://docs.unity3d.com/ScriptReference/CharacterController.Move.html" rel="nofollow">the doc of the Move function</a>)
A more complex move function taking absolute movement deltas.
</blockquote>To get this, use <a href="https://docs.unity3d.com/ScriptReference/Transform.TransformDirection.html" rel="nofollow">Transform.TransformDirection</a> like this
worldMove = transform.TransformDirection(moveVector);
controller.Move (worldMove * Time.deltaTime);
<strong>EDIT</strong> regarding your issue with the controller moving a bit after releasing the input:
That's because GetAxis
gives you a smoothed value. Replace GetAxis
by GetAxisRaw
and it should work
Modify the final moving code to
controller.Move(moveVector.z * transform.forward * Time.deltaTime);
controller.Move(moveVector.x * transform.right * Time.deltaTime);
controller.Move(moveVector.y * transform.up * Time.deltaTime);
Alternatively, suppose your character is <strong>only rotated about the Y axis</strong>, you can look into rotating your moveVector by your character's Y rotation so moveVector's forward points parallel to your chracter's forward.
I found a good explaination of rotating a vector here: <a href="https://answers.unity.com/questions/46770/rotate-a-vector3-direction.html" rel="nofollow">https://answers.unity.com/questions/46770/rotate-a-vector3-direction.html</a>
Rotating a vector:
moveVector = Quaternion.Euler(0, transform.eulerAngles.y, 0) * moveVector;