Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
1
Question by brandoncluff · Feb 06, 2018 at 03:39 AM · c#unity 5camera rotatecamera movementgimbal-lock

C# 360 Orbital Camera Controller (Gimbal Lock Issue)

I have a stationary cube in my scene that I'm orbiting a camera around. I have my MainCamera nested under a GameObject that I'm calling 'OrbitalCamera'.

I setup the script so that a click (or tap) and drag will rotate the camera around the object in space so it feels like you're rotating the cube (ie: if I click the top of a face on the cube, and pull down, I'm rotating the X value) but you'll actually be rotating the camera.

For the most part, my script works. However, after rotating the Y so much, the camera is upside down and the X gets inverted. Here's my (updated) script:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class OrbitalCamera : MonoBehaviour {
     public bool cameraEnabled;
 
     [SerializeField] private float touchSensitivity = 5f;
     [SerializeField] private float orbitDampening = 10f;
 
     protected Transform xFormCamera;
     protected Transform xFormParent;
     protected Vector3 localRotation;
     protected float cameraDistance;
 
     void Start () {
         cameraEnabled = true;
         xFormCamera = transform;
         xFormParent = transform.parent;
         cameraDistance = transform.position.z * -1;
     }
     
     void LateUpdate () {
         if (cameraEnabled) {
             if (Input.GetMouseButton(0)) {
                 if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0) {
                     localRotation.x += Input.GetAxis("Mouse X") * touchSensitivity;
                     localRotation.y -= Input.GetAxis("Mouse Y") * touchSensitivity;
                 }
             }
         }
 
         // TODO:: FIX CAMERA ROTATION / GIMBAL LOCK ISSUE
         
         Quaternion yaw = Quaternion.AngleAxis(localRotation.x, transform.up);
         Quaternion pitch = Quaternion.AngleAxis(localRotation.y, transform.right);
         //Quaternion qt = Quaternion.Euler(localRotation.y, localRotation.x, 0);
 
         // NOTE:: ROTATING PITCH AND YAW SEPARATELY WORK FLAWLESSLY, BUT ROTATION SHOULD HAPPEN TOGETHER
         //xFormParent.rotation = Quaternion.Slerp(xFormParent.rotation, pitch, Time.deltaTime * orbitDampening);
         //xFormParent.rotation = Quaternion.Slerp(xFormParent.rotation, yaw, Time.deltaTime * orbitDampening);
 
         // NOTE:: MULTIPLYING PITCH AND YAW STILL PRODUCES GIMBAL LOCK AND CAMERA SPINS INFINITELY AT CERTAIN ANGLES
         xFormParent.rotation = Quaternion.Slerp(xFormParent.rotation, pitch * yaw, Time.deltaTime * orbitDampening);
 
         // NOTE:: USING QUATERNION EULERS GENERATES A GIMBAL LOCK AND CAMERA DOES NOT SPIN 
         //xFormParent.rotation = Quaternion.Lerp(xFormParent.rotation, qt, Time.deltaTime * orbitDampening);
     }
 
 }

Is there a good method to achieve this type of 360 camera? I'd like dragging from right to left to always move the camera left and dragging left to right to always move the camera right -- no matter how the camera is oriented.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image brandoncluff · Feb 14, 2018 at 04:09 AM 0
Share

I still have not fully figured this out, but I definitely understand the problem better. I've found tons of solutions on forums that suggest clamping the pitch so that the camera can't pass the object on the top or bottom and 'flip' itself. I still would like help on this issue. Thank you.

avatar image Harinezumi brandoncluff · Feb 14, 2018 at 02:01 PM 0
Share

This is why I wrote I always run into issues: at first it seems logical that combining the 2 rotations should work, but then something happens, and it breaks. $$anonymous$$aybe if you apply them one after the other, and use the updated transform.up and transform.right vectors...

Another possible solution is that you parent your camera to a rotating object, set a displacement (for example (0, 0, -5)), and then just rotate the parent object, without fear of gimbal lock?
I think I solved this the last time this way, parenting my camera. This also has the advantage that zoo$$anonymous$$g/getting closer to the target is almost done!

avatar image brandoncluff Harinezumi · Feb 14, 2018 at 07:17 PM 0
Share

Thanks for being the only person to reply on this issue in general. I currently have an empty object called 'OrbitalCamera' and the '$$anonymous$$ainCamera' as the child, with the script on it. I'm manipulating the 'OrbitalCamera' rotation with this script via 'xFormParent'.

Additionally, I've tried modifying one after the other as that makes a lot of sense, but I'm still running into the same issue.

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Harinezumi · Feb 06, 2018 at 10:32 AM

If you want completely free rotation you need to eliminate Quaternion.Euler() and related functions from your code (because Euler angles can't properly represent all rotations without gimbal lock). Instead you could use Quaternion.AngleAxis() for the separate axes.
Also, Quaternion.Slerp() is a lot more useful than Lerp(), because it correctly "wraps around".

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image brandoncluff · Feb 06, 2018 at 06:39 PM 0
Share

Thanks for the advice - I'll give this a shot after work. If you think this conversion will be simple with my current code, post a snippet and I'll 'accept' this answer. Otherwise, I think I have some messing-around to do.

avatar image Harinezumi brandoncluff · Feb 07, 2018 at 09:04 AM 0
Share

No, sorry, I didn't post a snippet, because I always run into issues when doing rotations, even when it seems something simple. The solution will be something similar to:

 Quaternion yaw = Quaternion.AngleAxis(localRotation.x, transform.up);
 Quaternion pitch = Quaternion.AngleAxis(localRotation.y, transform.right);
 xFormParent.rotation = yaw * pitch;

I hope this helps!

avatar image brandoncluff Harinezumi · Feb 07, 2018 at 04:37 PM 1
Share

This is doing some freaky stuff. The initial rotation works, but if rotated too far, the camera starts orbiting like crazy. It looks like the yaw and pitch both work perfectly separately... but not together for some reason. I updated my script and will continue to test.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

510 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

FPS Character not moving in relation to direction/rotation 0 Answers

Text that always looks at you 1 Answer

How to rotate camera diagonally over players shoulder while still facing towards players direction 0 Answers

3d camera not working as I want it to 0 Answers

Make continuous camera rotation whilst holding the RMB 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges