- Home /
Why is my movement inverted to the changed camera angle?
Hi all,
I'm making a simple 3th person movement script. I have a camera following the character and whilst pressing right mouse button the camera orbits around the character nicely. The character then snaps into the direction of the camera when a movement command is given.
Now the problem I have is that after if move the camera to face one of the sides and move the character that the actual movement angles move to the opposite sides.
I tried to make my question clearer with a drawing. This is a top-down view of my character. As you can see in the drawing when I move my camera 90° to one side and want to move forward the forward movement is actually moving the character backwards. And when I move my camera 45° to one side the movement changes 45° degrees to the opposite side. When I move my camera 180° all the controls are normal.
It is like the movement vectors are moving in an equal angle to the opposite side of the camera movement I have this problem at any change of camera angle.
I'm very new to scripting and Unity3D so I'm not sure if this problem might lie in a wrong Unity3D setting or in an actual scripting flaw.
Hope someone could point me to where my error might be.
Thank you.

 using UnityEngine;
 using System.Collections;
 
 public class TP_Controller: MonoBehaviour 
 {
     public static CharacterController CharacterController; 
     public static TP_Controller Instance;
     
         
     void Awake() 
     {
         CharacterController = GetComponent("CharacterController") as CharacterController;
         Instance = this;
         TP_Camera.UseExistingOrCreateNewMainCamera();
     }
     
     
     void Update() 
     {
         if (Camera.mainCamera == null)
         {
             return;
         }
         
         GetLocomotionInput();
         
         TP_Motor.Instance.UpdateMotor();
     }
     
     void GetLocomotionInput()
     {
         // Deze var aanpassen voor deadzone.
         var deadZone = 0.1f;
         
         TP_Motor.Instance.MoveVector = Vector3.zero;
         
         if (Input.GetAxis("Vertical") > deadZone || Input.GetAxis("Vertical") < -deadZone)
             TP_Motor.Instance.MoveVector += new Vector3(0 , 0, Input.GetAxis ("Vertical"));
         
         if (Input.GetAxis("Horizontal") > deadZone || Input.GetAxis("Horizontal") < -deadZone)
             TP_Motor.Instance.MoveVector += new Vector3(Input.GetAxis ("Horizontal"), 0, 0);
     }
 }
 using UnityEngine;
 using System.Collections;
 
 public class TP_Camera : MonoBehaviour 
 {
     public static TP_Camera Instance;
     public Transform TargetLookAt;
     public float Distance = 5f;
     public float DistanceMin = 3f;
     public float DistanceMax = 10f;
     public float DistanceSmooth = 0.05f;
     public float X_MouseSensitivity = 5f;
     public float Y_MouseSensitivity = 5f;
     public float MouseWheelSensitivity = 5f;
     public float X_Smooth = 0.05f;
     public float Y_Smooth = 0.1f;
     public float Y_MinLimit = -40f;
     public float Y_MaxLimit = 80f;
     private float mouseX = 0f;
     private float mouseY = 0f;
     private float velX = 0f;
     private float velY = 0f;
     private float velZ = 0f;
     private float velDistance = 0f;
     private float startDistance = 0f;
     private Vector3 position = Vector3.zero;
     private Vector3 desiredPosition = Vector3.zero;
     private float desiredDistance = 0f;
     
     void Awake()
     {
         Instance = this;
     }
 
     void Start() 
     {
         Distance = Mathf.Clamp(Distance, DistanceMin, DistanceMax);
         startDistance = Distance;
         Reset();
     }
     
     void LateUpdate() 
     {
         if (TargetLookAt == null)
             return;
         
         HandlePlayerInput();
         
         CalculateDesiredPosition();
         
         UpdatePosition();
     }
     
     void HandlePlayerInput()
     {
         var deadZone = 0.01f;
         
         if (Input.GetMouseButton(1))
         {
             // The RMB is down get mouse Axis input
             mouseX += Input.GetAxis("MouseX") * X_MouseSensitivity;
             mouseY -= Input.GetAxis("MouseY") * Y_MouseSensitivity;
         }
         
         // This is where the limit of the mouseY is implemented
         mouseY = Helper.ClamAngle(mouseY, Y_MinLimit, Y_MaxLimit);
         
         if (Input.GetAxis("Mouse ScrollWheel") < -deadZone || Input.GetAxis("Mouse ScrollWheel") > deadZone)
         {
             desiredDistance = Mathf.Clamp(Distance - Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity, 
                 DistanceMin, DistanceMax);    
         }
     }
     
     void CalculateDesiredPosition()
     {
         // Evaluate distance
         Distance = Mathf.SmoothDamp(Distance, desiredDistance, ref velDistance, DistanceSmooth);
         // Calculate desired position
         desiredPosition = CalculatePosition(mouseY, mouseX, Distance);
     }
     
     Vector3 CalculatePosition(float rotationX, float rotationY, float distance)
     {
         Vector3 direction = new Vector3(0, 0, -distance);
         Quaternion rotation = Quaternion.Euler(rotationX, rotationY, 0);
         return TargetLookAt.position + rotation * direction;
     }
     
     void UpdatePosition()
     {
         var posX = Mathf.SmoothDamp(position.x, desiredPosition.x, ref velX, X_Smooth);
         var posY = Mathf.SmoothDamp(position.y, desiredPosition.y, ref velY, Y_Smooth);
         var posZ = Mathf.SmoothDamp(position.z, desiredPosition.z, ref velZ, X_Smooth);
         position = new Vector3(posX,posY,posZ);
         
         transform.position = position;
         transform.LookAt(TargetLookAt);
     }
     
     public void Reset()
     {
         mouseX = 0;
         mouseY = 10;
         Distance = startDistance;
         desiredDistance = Distance;
     }
     
     public static void UseExistingOrCreateNewMainCamera()
     {
         GameObject tempCamera;
         GameObject targetLookAt;
         TP_Camera myCamera;
         
         if (Camera.mainCamera != null)
         {
             tempCamera = Camera.mainCamera.gameObject;
         }
         else
         {
             tempCamera = new GameObject("Main Camera");
             tempCamera.AddComponent("Camera");
             tempCamera.tag = "MainCamera";
         }
         
         tempCamera.AddComponent("TP_Camera");
         myCamera = tempCamera.GetComponent("TP_Camera") as TP_Camera;
         
         targetLookAt = GameObject.Find ("targetLookAt") as GameObject;
         
         if (targetLookAt == null)
         {
             targetLookAt = new GameObject("targetLookAt");
             targetLookAt.transform.position = Vector3.zero;
         }
         
         myCamera.TargetLookAt = targetLookAt.transform;
     }
 }
 using UnityEngine;
 using System.Collections;
 
 public class TP_Motor : MonoBehaviour 
 {
     public static TP_Motor Instance;
     public float MoveSpeed = 10f;
     public Vector3 MoveVector { get; set; }
     
     
     void Awake() 
     {
         Instance = this;
     }
     
     public void UpdateMotor() 
     {
         SnapAlignCharacterWithCamera();
         ProcessMotion();
     }
     
     void ProcessMotion()
     {
         // Transform MoveVector to World Space
         MoveVector = transform.InverseTransformDirection (MoveVector);
         
         // Normalize MoveVector if Magnitude > 1
         if (MoveVector.magnitude > 1)
         {    
             MoveVector = Vector3.Normalize(MoveVector);
         }
         
         // Multiply MoveVector by MoveSpeed
         MoveVector *= MoveSpeed;
         
         // Multiply MoveVector by DeltaTime
         MoveVector *= Time.deltaTime;
             
         // Move the Caracter in World Space
         TP_Controller.CharacterController.Move(MoveVector);
     }
     
     void SnapAlignCharacterWithCamera()
     {
         if(MoveVector.x != 0 || MoveVector.z != 0)
         {
             transform.rotation = Quaternion.Euler(transform.eulerAngles.x, Camera.mainCamera.transform.eulerAngles.y, transform.eulerAngles.z);        
         }
     }
 }
 using UnityEngine;
 using System.Collections;
 
 public static class Helper
 {
     public static float ClamAngle(float angle, float min, float max)
     {
         do
         {
             if(angle < -360)
                 angle += 360;
             if(angle > 360)
                 angle -= 360;
         } while (angle < -360 || angle > 360);
         
         return Mathf.Clamp (angle, min, max);
     }
 }
 
Probably not the cleanest solution but see if the formulas in this code helps with your problem? It is supposed to let the character move forward/backward/etc relative to how the camera is facing.
 public void OnInput_AWSD$$anonymous$$ovement(int param)
     {
         reachedInteractTarget = false; // to turn off auto move in case it was on
 
         switch (param)
         {
             case 1:    // Forward
             {
                 if (Input$$anonymous$$anager.Instance.IsActive(inputIdx[5])) _actor.$$anonymous$$ove(_camTr.forward - _camTr.right, true); // left is held too
                 else if (Input$$anonymous$$anager.Instance.IsActive(inputIdx[6])) _actor.$$anonymous$$ove(_camTr.forward + _camTr.right, true); // right is held too
                 else _actor.$$anonymous$$ove(_camTr.forward, true);
             } break;
 
             case 2: // Backward
             {
                 if (Input$$anonymous$$anager.Instance.IsActive(inputIdx[5])) _actor.$$anonymous$$ove((_camTr.forward * -1) - _camTr.right, true); // left is held too
                 else if (Input$$anonymous$$anager.Instance.IsActive(inputIdx[6])) _actor.$$anonymous$$ove((_camTr.forward * -1) + _camTr.right, true); // right is held too
                 else _actor.$$anonymous$$ove(_camTr.forward * -1, true);
             } break;
 
             case 3: // Left
             {
                 if (Input$$anonymous$$anager.Instance.IsActive(inputIdx[3])) _actor.$$anonymous$$ove((_camTr.right * -1) + _camTr.forward, true); // foward is held too
                 else if (Input$$anonymous$$anager.Instance.IsActive(inputIdx[4])) _actor.$$anonymous$$ove((_camTr.right + _camTr.forward) * -1, true); // backward is held too
                 else _actor.$$anonymous$$ove(_camTr.right * -1, true);
             } break;
 
             case 4: // Right
             {
                 if (Input$$anonymous$$anager.Instance.IsActive(inputIdx[3])) _actor.$$anonymous$$ove(_camTr.right + _camTr.forward, true); // foward is held too
                 else if (Input$$anonymous$$anager.Instance.IsActive(inputIdx[4])) _actor.$$anonymous$$ove(_camTr.right - _camTr.forward, true); // backward is held too
                 else _actor.$$anonymous$$ove(_camTr.right, true);
             } break;
         }
     }
You need to post your script. Without a script all anyone will have is guesses.
Ok added all my scripts since I'm unsure where the flaw may be.
Sorry for the wall of text.
@Leslie; your script looks useful but I would like to know if there is an easier way to fix my problem.
Thank you
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                