Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Fast camera rotation problem

Discussion in 'Scripting' started by Aspiron94, Dec 13, 2019.

  1. Aspiron94

    Aspiron94

    Joined:
    Nov 2, 2016
    Posts:
    12
    Hi everyone,

    I've searched quite a bit to find a solution to the problem that I have.
    Now the problem is, as I want to rotate the camerathere isn't a problem.
    But the problem occurs when I move the mouse to fast. Then my camera makes a weird movement.
    Is there someone that has a solution to this? You're most welcome.

    Here is the code that I use on my camera:


    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class Camera_Controller_1 : MonoBehaviour
    7. {
    8.     public static Camera_Controller_1 instance;
    9.  
    10.     public Transform cameratransform;
    11.  
    12.     //KEYS
    13.     public KeyCode moveForward = KeyCode.Z;
    14.     public KeyCode moveBackward = KeyCode.S;
    15.     public KeyCode moveLeft = KeyCode.Q;
    16.     public KeyCode moveRight = KeyCode.D;
    17.  
    18.     public KeyCode rotateLeft = KeyCode.A;
    19.     public KeyCode rotateRight = KeyCode.E;
    20.     //ALT KEYS
    21.     public KeyCode moveForwardALT = KeyCode.UpArrow;
    22.     public KeyCode moveBackwardALT = KeyCode.DownArrow;
    23.     public KeyCode moveLeftALT = KeyCode.LeftArrow;
    24.     public KeyCode moveRightALT = KeyCode.RightArrow;
    25.  
    26.     //FLOATS
    27.     public float normalSpeed;
    28.     public float fastSpeed;
    29.     public float movementSpeed;
    30.     public float movementTime;
    31.  
    32.     public float rotationAmount;
    33.  
    34.     Vector3 rotateStartPosition;
    35.     Vector3 rotateCurrentPosition;
    36.     Quaternion newRotation;
    37.  
    38.     private void Awake()
    39.     {
    40.         instance = this;
    41.     }
    42.  
    43.     // Start is called before the first frame update
    44.     void Start()
    45.     {
    46.         newPosition = transform.position;
    47.         newRotation = transform.rotation;
    48.     }
    49.  
    50.     // Update is called once per frame
    51.     void Update()
    52.     {
    53.         HandleMovementInput();
    54.         HandleMouseInput();
    55.     }
    56.  
    57.     void HandleMouseInput()
    58.     {
    59.         if (Input.GetMouseButtonDown(2))
    60.             rotateStartPosition = Input.mousePosition;
    61.  
    62.         if (Input.GetMouseButton(2))
    63.         {
    64.             rotateCurrentPosition = Input.mousePosition;
    65.             Vector3 difference = rotateStartPosition - rotateCurrentPosition;
    66.             rotateStartPosition = rotateCurrentPosition;
    67.             newRotation *= Quaternion.Euler(Vector3.up * (-difference.x / 5f));
    68.         }
    69.     }
    70.  
    71.     void HandleMovementInput()
    72.     {
    73.         if (Input.GetKey(KeyCode.LeftShift))
    74.             movementSpeed = fastSpeed;
    75.         else
    76.             movementSpeed = normalSpeed;
    77.  
    78.         if (Input.GetKey(moveForward) || Input.GetKey(moveForwardALT))
    79.             newPosition += (transform.forward * movementSpeed);
    80.  
    81.         if (Input.GetKey(moveBackward) || Input.GetKey(moveBackwardALT))
    82.             newPosition += (transform.forward * -movementSpeed);
    83.  
    84.         if (Input.GetKey(moveLeft) || Input.GetKey(moveLeftALT))
    85.             newPosition += (transform.right * -movementSpeed);
    86.  
    87.         if (Input.GetKey(moveRight) || Input.GetKey(moveRightALT))
    88.             newPosition += (transform.right * movementSpeed);
    89.  
    90.         if (Input.GetKey(rotateLeft))
    91.             newRotation *= Quaternion.Euler(Vector3.up * rotationAmount);
    92.  
    93.         if (Input.GetKey(rotateRight))
    94.             newRotation *= Quaternion.Euler(Vector3.up * -rotationAmount);
    95.  
    96.         transform.position = Vector3.Lerp(transform.position, newPosition, Time.deltaTime * movementTime);
    97.         transform.rotation = Quaternion.Lerp(transform.rotation, newRotation, Time.deltaTime * movementTime);
    98.     }
    99. }
    100.  
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,835
    What does "a weird movement" mean?

    A common problem with fast sudden rotations (or movements in general) in movies or on computers is that you only have a limited framerate, and short sharp movements destroy the illusion of continuous movement. A fast but continuous rotation can also look like a different speed than it actually is--and can even look like it's spinning backwards--due to the wagon-wheel effect.
     
    Joe-Censored likes this.
  3. Aspiron94

    Aspiron94

    Joined:
    Nov 2, 2016
    Posts:
    12
  4. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,315
    Quaternions will always represent the shortest possible rotation to reach the target. When you rotate too fast, you go over 180 degrees in a frame, and your lerp immediately starts rotating the opposite way, as that is now the shorter path to travel.

    Easiest fix is to limit the max rotation amount to 179 degrees in a frame. Nobody needs to rotate that fast in normal gameplay.

    There are things you can do to actually fix this, but they are more complicated than a one line max function and not worth the trouble.
     
    Aspiron94 likes this.
  5. Aspiron94

    Aspiron94

    Joined:
    Nov 2, 2016
    Posts:
    12
    Thanks for the answer, I'm not a math expert, but it seems one value (now known as rotationLimiter) has to do something with the rotation speed.
    I've made it a higher value and now the problem is gone. Thanks again!


    Code (CSharp):
    1. if (Input.GetMouseButton(2))
    2.         {
    3.             rotateCurrentPosition = Input.mousePosition;
    4.             Vector3 difference = rotateStartPosition - rotateCurrentPosition;
    5.             rotateStartPosition = rotateCurrentPosition;
    6.             newRotation *= Quaternion.Euler(Vector3.up * (-difference.x / rotationLimiter));
    7.         }