# Move rigidbody using WASD keys but rotate it based on camera/mouse movement

I am very new to unity and my scripts are based on some scripts found on the web.

I want to make a first person view so the camera is attached to my rigidbodys head. Then i want to move my rigidbody based on keyboard input (wasd) and rotate it using the mouse movement.

Until now, i used the following code for moving my rigidbody:

void Update() {

/* calculate rigidbody movement */
movement = new Vector3( Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")).normalized;

/* calculate mouse look to rotate the rigidbody*/
mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
mouseDelta = Vector2.Scale(mouseDelta, new Vector2(sensitivity * smoothing, sensitivity * smoothing));
smoothV.x = Mathf.Lerp(smoothV.x, mouseDelta.x, 1f / smoothing);
smoothV.y = Mathf.Lerp(smoothV.y, mouseDelta.y, 1f / smoothing);
mouseLook += smoothV;

}

void FixedUpdate() {

/* apply rigidbody movement from Update() */
transform.Translate( movement * moveSpeed * Time.deltaTime );
/* apply rigidbody rotation from Update() */
transform.localRotation = Quaternion.AngleAxis(mouseLook.x, transform.up);
/* apply camera rotation from Update() */
Camera.main.transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);

}


I learned today that i dont have to move a rigidbody's transform but now i am totally confused and it seems i have to restart my whole (first!) project.

So when i use MovePosition and MoveRotation, how do i rotate it based on the camera perspective/mouse movement?

I think the movement Vector is ok so i can simply rewrite the FixedUpdate to something like

rigidbody.MovePosition(movement * speed * Time.deltaTime)


but i am totally stuck on how to apply the camera rotation to my rigidbody to use it like

void FixedUpdate() {
/* move the rigidbody */
rigidbody.MovePosition(movement * moveSpeed * Time.deltaTime);
/* rotate the camera */
camera.transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);

/* but how can i rotate the rigidbody based on the cameras rotation??? */
rigidbody.MoveRotation(?????);

}


I hope its clear what i want, thank you!

• You have the local rotation of the camera you can pass that into MoveRotation(), Something like this MoveRotation(Quaternion.Euler(Camera.main.transform.localRotation.eulerAngles)) Apr 23 '19 at 6:51
• Oh and I highly recommend caching the camera and rigidbody into variables and use them instead of calling Camera.main and GetComponent<Rigidbody>() each Fixed Update Apr 23 '19 at 6:57
• First of all thank you! I have cached the variables its just not in the question, sorry. I tried to apply your suggestions but it doesnt work as expected could you be a bit more specific on that? And also if you make it an answer i could accept it. Apr 23 '19 at 15:39

This is the movement code for my character script:

private Camera cam;

private void Start ()
{
cam = Camera.main;
}

private void FixedUpdate ()
{
Move();
}

private void Move ()
{
// Getting the direction to move through player input
float hMove = Input.GetAxis("Horizontal");
float vMove = Input.GetAxis("Vertical");
float speed = 5.0f;

// Get directions relative to camera
Vector3 forward = cam.transform.forward;
Vector3 right = cam.transform.right;

// Project forward and right direction on the horizontal plane (not up and down), then
// normalize to get magnitude of 1
forward.y = 0;
right.y = 0;
forward.Normalize();
right.Normalize();

// Set the direction for the player to move
Vector3 dir = right * hMove + forward * vMove;

// Set the direction's magnitude to 1 so that it does not interfere with the movement speed
dir.Normalize();

// Move the player by the direction multiplied by speed and delta time
transform.position += dir * speed * Time.deltaTime;

// Set rotation to direction of movement if moving
if (dir != Vector3.zero)
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(forward), 0.2f);
}

}


and this is my camera script (sorry about the wierd indenting, copying and pasting from visual studio messed it up and I don't know how to fix it):

using UnityEngine;

public class CameraScript : MonoBehaviour
{
// Angle to clamp the camera at on the up/down axis
private const float Y_ANGLE_MIN = -50.0f;
private const float Y_ANGLE_MAX = 50.0f;

// The game object's transform for the camera to look at
public Transform target;

private Transform camTransform;

// Distance between the player and the camera
private float distanceBetween = 2f;
private float currentX = 0.0f;
private float currentY = 0.0f;

// How much the camera reacts to movement of the mouse
private float sensitivityX = 6.0f;
private float sensitivityY = 3.0f;

private void Start()
{
camTransform = transform;
}

private void Update()
{
currentX += Input.GetAxis("Mouse X") * sensitivityX;
currentY -= Input.GetAxis("Mouse Y") * sensitivityY;

currentY = Mathf.Clamp(currentY, Y_ANGLE_MIN, Y_ANGLE_MAX);
}

private void LateUpdate()
{
int layerMask = 1 << 9;

Vector3 dir = new Vector3(0.5f, 1.6f, -distanceBetween);
Quaternion rot = Quaternion.Euler(currentY, currentX, 0);
camTransform.position = target.position + rot * dir;

}
}


If you need any clarification or find any errors, please let me know :) Also, this is my first time answering, so if I'm missing something please tell me that too.

Good luck!

• You make the same mistake like me. You use "transform.translate" to move your character, but that kind of beams the character to the position you've told him ignoring the physics engine. I already used similar code as you might see in my question if you read it again carefully. This way he can glitch throu walls and exactly thats the reason for my question. See gamedev.stackexchange.com/a/154463/126411 for clarification and why you should change your code. Apr 24 '19 at 8:36

Okay so after quickly trying your code I see that the rotation of the camera was not working on X-Axis,

The problem was at this line in the FixedUpdate()

camera.transform.localRotation = Quaternion.AngleAxis(-mouseLook.y, Vector3.right);

So I have modified FixedUpdate()

    void FixedUpdate()
{
rigidbody.MovePosition(movement * moveSpeed * Time.deltaTime);

// I tried my best to explain this in my answer
cam.transform.localRotation = Quaternion.Euler(-mouseLook.y, mouseLook.x, 0f);

rigidbody.MoveRotation(Quaternion.Euler(cam.transform.localRotation.eulerAngles));
}


Notice that how I put the mouseLook.x and mouseLook.y in different order, now this is tricky part to explain but I will try to explain,

Assume we have set our pointer to 0,0 on the screen, when we move the mouse on the left it will return minus value on X-Axis and when we move the mouse right it will return positive value on the X-Axis,

Same for Y-Axis when we move Up it returns positive value and negative when we move down

Now assume we have move the mouse left, now in order to rotate the camera to the left side we have to rotate it around Y-Axis with some minus values

Imagine mouseLook Returns -1,0 when we move left, now to rotate camera on left we need to do 0, -1, 0 on its rotation,

Same goes for Y-Axis, we move the pointer up it returns 0,1, now to rotate camera up we need to do -1, 0, 0

I know it is very confusing and my explaination skills are equally horrible but to keep things simple remember this,

to rotate camera up we need to manipulate its X-Axis with minus values,
to rotate camera down we need to manipulate its X-Axis with plus values,
to rotate camera left we need to manipulate its Y-Axis with minus value,
to rotate camera Right we need to manipulate its Y-Axis with plus value.