1
\$\begingroup\$

i am building a camera rotation script like in fps. Everything is setup and working except that camera rotation resets to zero at the start of game which i dont want. This is the camera rotation i have set:

enter image description here

This is rotation of character my script is attached to: enter image description here

And after hitting play it resets camera rotation to (0,0,0). i want it to remain how i have set it in inspector. i am using quaternion.slerp to rotate camera around to rotations on the basis of touch inputs. After reset to (0,0,0) everything works fine.please help, i have always had a hard time understanding quaternions.

this is the script:

    public class ScreenCharacterController : MonoBehaviour {

     private Camera mainCamera;
     private CharacterController character;
     private int leftFingerID = -1;
     private int rightFingerID = -1;
     private Vector2 leftFingerInput;
     private Vector2 rightFingerInput;
     private float xAxisRotation;
     private float yAxisRotation;
     [SerializeField] private float minXRotation;
     [SerializeField] private float maxXRotation;
     [SerializeField] private float minYRotation = -25f;
     [SerializeField] private float maxYRotation = 25f;
     [SerializeField] private float cameraRotationSpeed = 20f;

     void Start()
     {
         mainCamera = Camera.main;
     }

     void Update()
     {
        //for touch
         TouchInput();

        //for calculating rotation vaues
         CalculateAndClampRotation();

         RotateCamera();
     }


     void TouchInput()
     {
         foreach (Touch touch in Input.touches)
         {
             if (touch.phase == TouchPhase.Began)
             {
                 //Left Touch
                 if (touch.position.x < Screen.width / 2)
                 {
                     leftFingerID = touch.fingerId;

                 }
                 //Right touch
                 else
                 {
                     rightFingerID = touch.fingerId;

                 }
             }
             else if (touch.phase == TouchPhase.Moved)
             {
                 //Left Touch
                 if (touch.position.x < Screen.width / 2)
                 {
                     if (leftFingerID == touch.fingerId)
                     {

                     }

                 }
                 //Right touch
                 else
                 {
                     if (rightFingerID == touch.fingerId)
                     {
                         rightFingerInput = touch.deltaPosition * Time.smoothDeltaTime;

                     }

                 }
             }
             else if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
             {
                 if (touch.fingerId == leftFingerID)
                 {
                     leftFingerID = -1;

                 }
                 else if (touch.fingerId == rightFingerID)
                 {
                     rightFingerID = -1;
                     rightFingerInput = new Vector2(0, 0);
                 }

             }
         }
     }

 void RotateCamera()
     {
         Quaternion currentRotation = mainCamera.transform.localRotation;
         Quaternion targetRotation = Quaternion.identity;

         targetRotation = Quaternion.Euler((mainCamera.transform.localRotation.x - yAxisRotation),
         -(mainCamera.transform.localRotation.y - xAxisRotation), 0f);

         mainCamera.transform.localRotation = Quaternion.Slerp(currentRotation, targetRotation, 0.5f);

     }

     void CalculateAndClampRotation()
     {
         xAxisRotation += rightFingerInput.x * cameraRotationSpeed;
         yAxisRotation += rightFingerInput.y * cameraRotationSpeed;
         xAxisRotation = Mathf.Clamp(xAxisRotation, minXRotation, maxXRotation);
         yAxisRotation = Mathf.Clamp(yAxisRotation, minYRotation, maxYRotation);
     }

 }
\$\endgroup\$
  • \$\begingroup\$ It looks like you forgot to initialize your xAxisRotation and yAxisRotation variables to their starting values in Start(). \$\endgroup\$ – DMGregory Oct 2 '19 at 9:51
  • \$\begingroup\$ tried setting those initial values to the camera's current x and y rotations respectively but it still doesn't works. \$\endgroup\$ – Anmol Deep Oct 2 '19 at 13:44
0
\$\begingroup\$

Thanks @DMGregory for pointing this out. Fixed it by initializing xAxisRotation and yAxisRotation variables to camera's start rotations and by changing the target rotation.

Initialized those at start method and i have also carefully set clamping values according to default camera x and y rotations. My start method now looks like this:

void Start()
    {
        mainCamera = Camera.main;

        xAxisRotation = mainCamera.transform.eulerAngles.y;
        yAxisRotation = mainCamera.transform.eulerAngles.x;

        minYRotation = xAxisRotation - minYRotation;
        maxYRotation = xAxisRotation + maxYRotation;

        minXRotation = yAxisRotation - minXRotation;
        maxXRotation = yAxisRotation + maxXRotation;

    }

Also changed this code:

Quaternion targetRotation = Quaternion.identity;

targetRotation = Quaternion.Euler((mainCamera.transform.localRotation.x - yAxisRotation),
         -(mainCamera.transform.localRotation.y - xAxisRotation), 0f);

to this:

Quaternion targetRotation = Quaternion.Euler(yAxisRotation, xAxisRotation, 0f);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.