- Home /
Reset player movement axes after camera rotation
I have a character controller and camera setup so that the camera moves with the player in a 3D top down configuration. I've scripted the ability to rotate the camera by holding shift and moving the mouse. Once the camera has been rotated and shift released, I want the axes of the player movement to reset to the new camera rotation so pressing "w" still causes the player to travel towards the top of the screen. My idea for the solution was to create a parent "playerAxes" for the player gameobject which rotates to the camera target when shift is released. However, my (attempted) implementation of this causes the player to go flying off the playing field.
cameraController:
public float RotationSpeed;
public Transform Target, Player, PlayerAxes;
float mouseX;
Quaternion lastTargetRotation;
void Start () {
transform.LookAt (Target);
}
void LateUpdate () {
CamControl();
}
void CamControl()
{
//Hold shift to move camera around player
if(Input.GetKey ("left shift")){
mouseX += Input.GetAxis ("Mouse X") * RotationSpeed;
transform.LookAt (Target);
Target.rotation = Quaternion.Euler (0, mouseX, 0);
}
if(Input.GetKeyUp ("left shift")){
PlayerAxes.rotation = transform.rotation;
}
}
CharacterController:
void PlayerMovement() {
float hor = Input.GetAxis ("Horizontal");
float ver = Input.GetAxis ("Vertical");
Vector3 playerMovement = new Vector3(hor, 0f, ver).normalized * speed * Time.deltaTime;
transform.Translate (playerMovement, Space.World);
if(playerMovement != new Vector3 (0f, 0f, 0f)){
transform.rotation = Quaternion.LookRotation (playerMovement);
}
}
Answer by unity_ek98vnTRplGj8Q · Apr 06, 2020 at 09:53 PM
Don't use a parent object here, since if you mess with the rotation of the parent object it will cause your player to change position (rotating the parent object will cause the player to orbit around the center of the parent object). Instead just keep track of the rotation about the y axis and then rotate your movement vector by that amount.
//In your camera script
public static float playerMovementAngle;
void Update () {
//...
if (Input.GetKeyUp ("left shift")) {
playerMovementAngle = mouseX;
}
}
//In your movement script
void PlayerMovement () {
float hor = Input.GetAxis ("Horizontal");
float ver = Input.GetAxis ("Vertical");
Vector3 playerMovement = new Vector3 (hor, 0f, ver).normalized * speed * Time.deltaTime;
//Rotate your movement vector by your camera rotation.
playerMovement = Quaternion.Euler (0, RotationSpeed.playerMovementAngle, 0) * playerMovement;
transform.Translate (playerMovement, Space.World);
if (playerMovement != new Vector3 (0f, 0f, 0f)) {
transform.rotation = Quaternion.LookRotation (playerMovement);
}
}