title: Unity Problem with Cinemachine when the Character is rotated
body: <p>I am trying to implement a 3D, Third person character movement using a Rigidbody and Cinemachine.
  The character should be able to walk on the ground and ceiling, as well as on the walls (only left and right wall, when facing the positive X-Axis).</p>
  <p>I achieved that by adding/changing a constant force to the Rigidbody, to change the gravity direction and rotating the character on x for up and down and z for right and left.</p>
  <p>The CinemachineBrain has a World Up Override set to the Characters transform and the CinemchineFreeLook Binding Mode is set to &quot;Simple Follow with World Up&quot;. This lets the camera/cinemachine orbits rotate relative to the Characters rotation.</p>
  <p>For now I have implemented 4 methods in my PlayerMovement Script, one for each gravity direction (up, down, left, right) each of them doing basically the same just with the changed rotation and gravity.</p>
  <p>The MoveUp() and MoveDown() methods work as expected.</p>
  <p>But I can't get the MoveLeft() and MoveRight() methods to work.</p>
  <p>The Problem is that the Character can't make a 360 degree rotation (here on the x axis) when adding the cameras angle but just a 180 degree rotation while facing positive or negative x (it feels like there is an invisible wall on the y axis.</p>
  <p>I somehow expect Cinemachine / the  <code>+ Camera.main.transform.eulerAngles.x;</code>  to be the problem here, but I can't figure out what it is exactly.</p>
  <p>This is my first Project in Unity / Game development in general - so i hope i gave all necessary information.</p>
  <p>Thanks for answers.</p>
  <p>And here is my Script:</p>
  <p>( I followed this tutorial to implement the basic movement and changed it to work with a Rigidbody : <a href="https://youtu.be/4HpC--2iowE" rel="nofollow noreferrer">https://youtu.be/4HpC--2iowE</a> )</p>
  <pre><code>public class PlayerMovement : MonoBehaviour
  {
  
      public float walkSpeed = 5f;
      public float runSpeed = 15f;
      public float idleSpeed = 0f;
  
      public string gravityDiretion = &quot;down&quot;;
      public ConstantForce gravity = new ConstantForce();
      private float actualSpeed;
  
      public float turnSmoothing = 0.1f;
      float turnSmoothVelocity;
      private Rigidbody character;
  
  
      private void Start()
      {
         character = GetComponent&lt;Rigidbody&gt;();
         gravity = gameObject.AddComponent&lt;ConstantForce&gt;();
      }
      private void FixedUpdate()
      {
          Move();
      }
  
  
      private void Move() 
      {
          if (gravityDiretion.Equals(&quot;up&quot;))
          {
              MoveUp();
          }
          else if (gravityDiretion.Equals(&quot;down&quot;))
          {
              MoveDown();
          }
          else if (gravityDiretion.Equals(&quot;right&quot;))
          {
              MoveRight();
          }
          else if (gravityDiretion.Equals(&quot;left&quot;))
          {
              MoveLeft();
          }
      }
  
      private void MoveUp()
      {
          gravity.force = new Vector3(0.0f, 9.81f, 0.0f);
  
          if (Input.GetKey(KeyCode.LeftShift))
          {
              actualSpeed = runSpeed;
          }
          else
          {
              actualSpeed = walkSpeed;
          }
  
          float horizonal = Input.GetAxisRaw(&quot;Horizontal&quot;); // 1 = left -1 righ
          float vertical = Input.GetAxisRaw(&quot;Vertical&quot;); // 1 = forward -1 bakwadrd
          Debug.Log(&quot;Axis Vertical = &quot; + vertical);
          Debug.Log(&quot;Axis Horizontal = &quot; + horizonal);
  
          Vector3 direction = new Vector3(horizonal, 0f, -vertical).normalized; //normalize to not moving faster when pressing two keys to walk diagonal
  
  
          if (direction.magnitude &gt;= 0.1f) // If lenght of the vecctor is &gt; 0
          {
              //Character Rotation
              float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + Camera.main.transform.eulerAngles.y; // The angle the character should turn to face forward
              Debug.Log(&quot;targetAngle = &quot; + targetAngle);
              float smoothedAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, - turnSmoothing);
              Debug.Log(&quot;smoothedAngle = &quot; + smoothedAngle);
              character.MoveRotation(Quaternion.Euler(180f, smoothedAngle, 0f));
  
              //Character Movement
              Vector3 moveDir = Quaternion.Euler(180f, targetAngle, 0f) * Vector3.forward;
              Debug.Log(&quot;Movedir = &quot; + moveDir.ToString());
              character.MovePosition(transform.position + moveDir.normalized * actualSpeed * Time.fixedDeltaTime);
          }
          else
          {
              actualSpeed = 0f;
          }
      }
  
      private void MoveDown()
      {
          //Gravity
          gravity.force = new Vector3(0.0f, -9.81f, 0.0f);
  
          if (Input.GetKey(KeyCode.LeftShift))
          {
              actualSpeed = runSpeed;
          }
          else
          {
              actualSpeed = walkSpeed;
          }
  
          float horizonal = Input.GetAxisRaw(&quot;Horizontal&quot;); // 1 = left -1 righ
          float vertical = Input.GetAxisRaw(&quot;Vertical&quot;); // 1 = forward -1 bakward
          Debug.Log(&quot;Axis Vertical = &quot; + vertical);
          Debug.Log(&quot;Axis Horizontal = &quot; + horizonal);
  
          Vector3 direction = new Vector3(horizonal, 0f, vertical).normalized; 
  
          if (direction.magnitude &gt;= 0.1f) 
          {
              //Character Rotation
              float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + Camera.main.transform.eulerAngles.y;
              float smoothedAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothing);
              character.MoveRotation(Quaternion.Euler(0f, smoothedAngle, 0f));
  
              //Character Movement
              Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
              Debug.Log(&quot;Movedir = &quot; + moveDir.ToString());
              character.MovePosition(transform.position + moveDir.normalized * actualSpeed * Time.fixedDeltaTime);
          }
          else
          {
              actualSpeed = 0f;
          }
      }
  
      private void MoveRight()
      {
          //Gravity
          gravity.force = new Vector3(9.81f, 0.0f, 0.0f);
  
          if (Input.GetKey(KeyCode.LeftShift))
          {
              actualSpeed = runSpeed;
          }
          else
          {
              actualSpeed = walkSpeed;
          }
  
          float horizonal = Input.GetAxisRaw(&quot;Horizontal&quot;);
          float vertical = Input.GetAxisRaw(&quot;Vertical&quot;);
          Debug.Log(&quot;Axis Vertical = &quot; + vertical);
          Debug.Log(&quot;Axis Horizontal = &quot; + horizonal);
  
          Vector3 direction = new Vector3( 0f, horizonal, vertical).normalized; 
  
  
          if (direction.magnitude &gt;= 0.1f) 
          {
  
              float targetAngle = Mathf.Atan2(direction.y, direction.z) * Mathf.Rad2Deg + Camera.main.transform.eulerAngles.x;
              Debug.Log(&quot;targetAngle = &quot; + targetAngle);
              float smoothedAngle = Mathf.SmoothDampAngle(transform.eulerAngles.x, targetAngle, ref turnSmoothVelocity, turnSmoothing);
              Debug.Log(&quot;smoothedAngle = &quot; + smoothedAngle);
              character.MoveRotation( Quaternion.Euler(targetAngle, 0f , 90f));
  
              //Character Movement
              Vector3 moveDir = Quaternion.Euler(targetAngle, 0.0f, 90f) * Vector3.forward;
              Debug.Log(&quot;Movedir = &quot; + moveDir.ToString());
              character.MovePosition(transform.position + moveDir.normalized * actualSpeed * Time.fixedDeltaTime);
          }
          else
          {
              actualSpeed = 0f;
          }
      }
  
  
      private void MoveLeft()
      {
          //Gravity
          gravity.force = new Vector3(-9.81f, 0.0f, 0.0f);
  
          if (Input.GetKey(KeyCode.LeftShift))
          {
              actualSpeed = runSpeed;
          }
          else
          {
              actualSpeed = walkSpeed;
          }
  
          float horizonal = Input.GetAxisRaw(&quot;Horizontal&quot;); 
          float vertical = Input.GetAxisRaw(&quot;Vertical&quot;); 
          Debug.Log(&quot;Axis Vertical = &quot; + vertical);
          Debug.Log(&quot;Axis Horizontal = &quot; + horizonal);
  
          Vector3 direction = new Vector3(0f, horizonal, vertical).normalized; 
  
  
          if (direction.magnitude &gt;= 0.1f)
          {
              //Character Rotation
              float targetAngle = Mathf.Atan2(direction.z, direction.y) * Mathf.Rad2Deg + Camera.main.transform.eulerAngles.x; 
              float smoothedAngle = Mathf.SmoothDampAngle(transform.eulerAngles.x, targetAngle, ref turnSmoothVelocity, turnSmoothing);
              character.MoveRotation(Quaternion.Euler(smoothedAngle, 0f, -90f));
  
              //Character Movement
              Vector3 moveDir = Quaternion.Euler(targetAngle, 0.0f, -90f) * Vector3.right;
              Debug.Log(&quot;Movedir = &quot; + moveDir.ToString());
              character.MovePosition(transform.position + moveDir.normalized * actualSpeed * Time.fixedDeltaTime);
          }
          else
          {
              actualSpeed = 0f;
          }
      }
  
  
  
      public void ChangeDravityDirection(string newGravityDirection)
      {
          gravityDiretion = newGravityDirection;  
      }
  
  </code></pre>