I’ve been trying to figure this out for a while but I can’t seem to get my player to move relative to the camera. When I press W and S I move up and down in world space and left and right in world space when I press A and D. How can I make it so that W moves me forward in the direction the camera is looking, A and D left and right of where the camera is looking and S moving towards the camera.
Here’s the player movement script:
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour
{
public float moveSpeed;
public float rotationSpeed;
Vector3 previousLocation;
Vector3 moveDirection;
void Update ()
{
moveDirection = Vector3.zero;
previousLocation = transform.position;
if (Input.GetKey (KeyCode.W)) moveDirection.z = 1;
if (Input.GetKey (KeyCode.S)) moveDirection.z = -1;
if (Input.GetKey (KeyCode.A)) moveDirection.x = -1;
if (Input.GetKey (KeyCode.D)) moveDirection.x = 1;
transform.position = Vector3.Lerp(transform.position, transform.position +
moveDirection.normalized, Time.fixedDeltaTime * moveSpeed);
if (moveDirection != Vector3.zero)
transform.rotation = Quaternion.Lerp(
transform.rotation, Quaternion.LookRotation(transform.position - previousLocation),
Time.fixedDeltaTime * rotationSpeed);
}
}
So if you want to move relative to the direction of the camera (or any object), then we first need to know the rotation of that object. So let’s add a reference in your script:
public Transform relativeTransform;
Next, instead of using absolute values, when setting your move direction, let’s use the direction the camera is facing:
Now, based off your code so far, it seems that you only want the player to move on a plane (only x and z directions), so we will want to remove any y movement that the camera’s rotation may have included.
moveDirection.y = 0f;
Here is the entire script, modified with a few extra changes. Basically, I just cleaned up and simplified the code so that the speed values aren’t arbitrary. Now moveSpeed is in units/second, and rotationSpeed is in degrees/second.
using UnityEngine;
using System.Collections;
public class TempPlayer : MonoBehaviour
{
public float moveSpeed;
public float rotationSpeed;
public Transform relativeTransform;
void Update()
{
Vector3 moveDirection = Vector3.zero;
if(Input.GetKey(KeyCode.W)) moveDirection += relativeTransform.forward;
if(Input.GetKey(KeyCode.S)) moveDirection += -relativeTransform.forward;
if(Input.GetKey(KeyCode.A)) moveDirection += -relativeTransform.right;
if(Input.GetKey(KeyCode.D)) moveDirection += relativeTransform.right;
moveDirection.y = 0f;
transform.position += moveDirection.normalized * moveSpeed * Time.deltaTime;
if(moveDirection != Vector3.zero)
transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(moveDirection), rotationSpeed * Time.deltaTime);
}
}
Just make sure to assign your camera to relativeTransform in the inspector. Hope this helps!