Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 /
avatar image
0
Question by boddole · Feb 18, 2015 at 02:09 PM · c#camerarotationquaternionmath

Trouble with Camera Rotation Math

Hello everyone, I've got a setup where the player (with a "analog stick") can rotate a camera around an object spherically (actually, the camera is anchored to another GameObject, and the GO rotates and takes the camera with it). My problem is that while I can get the up/down or left/right rotation to work, when I try to use both at the same time or one after another, the rotation gets "wobbly" and becomes increasingly incorrect.

My Method:

My thought was that I would "just" create the rotation for desired left/right and for desired up/down, then add them together, then add that to the current rotation. I'm not really sure which part of this is flawed (if not the entire idea), but any guidance is appreciated.

     public void RotateCamera(Vector2 horizVert)
     {
         //up and down:
         vertQ = Quaternion.Euler ( transform.right * ( (maxRotationSpeed * horizVert.y) * Time.deltaTime) );
         //verticalV = vertQ.eulerAngles;
 
         //left and right:
         horizQ = Quaternion.Euler ( Vector3.up * ( (maxRotationSpeed * horizVert.x) * Time.deltaTime) );
         //horizontalV = horizQ.eulerAngles;
 
         transform.rotation *= (vertQ * horizQ);
     }

Any thoughts are appreciated, thank you for reading.

Comment
Add comment · Show 2
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 meat5000 ♦ · Feb 19, 2015 at 04:28 AM 0
Share

Pack your up/down and left/right into a Vector2 and normalise it.

avatar image boddole · Feb 19, 2015 at 06:50 AM 0
Share

@meat5000:

Your suggestion is a bit over my head, if possible could you elaborate on: 1) How you pack a quaternion into a Vec2. 2) Once you've done 1 and normalized it, what do you do with it (make rotation *= Quat.Euler(Vec2) )?

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Rector · Feb 18, 2015 at 09:47 PM

I built something similar (but kind of opposite) from the MouseOrbit script in the Unity standard assets.

Really the big clue there is that keeping a hard value for cumulative X and Y rotation during runtime (in my code below, that's _cameraXRotation and _cameraYRotation) and rebuilding your rotation from scratch each time should do what you want. Try this little guy. I assume horizVert is just Input.GetAxis on your controller axes.

     void ApplyCameraRotationController(Vector2 horizVert) {
         _cameraXRotation = _cameraXRotation + horizVert.x * maxRotationSpeed * Time.deltaTime;
         _cameraYRotation = _cameraYRotation + horizVert.y * maxRotationSpeed * Time.deltaTime;
         transform.rotation = Quaternion.Euler(_cameraYRotation, _cameraXRotation, 0);
     }
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 boddole · Feb 19, 2015 at 04:26 AM 0
Share

@Rector:

->What you are doing is similar to what I ended up doing just to get something that works. I ended up using (before seeing your answer) Transform.RotateAround(). Would you happen to know if either way of doing this is "better / more efficient" than the other?

     public void RotateCamera(Vector2 horizVert)
     {
         transform.RotateAround(transform.position, Vector3.up, (maxRotationSpeed * horizVert.x) * Time.deltaTime);
         transform.RotateAround(transform.position, transform.right, (maxRotationSpeed * horizVert.y) * Time.deltaTime);
     }
avatar image Rector · Feb 19, 2015 at 08:24 PM 0
Share

Using two calls to RotateAround rather than setting the rotation directly once would give me pause, but that borders on just personal preference. I imagine that the implementation of RotateAround generally assumes that the position could change along with the rotation, which technically would result in a few more instructions, but I doubt that would amount to any noticeable performance issues using either in an *Update() or whatever.

avatar image boddole · Feb 20, 2015 at 04:53 AM 0
Share

@Rector:

->I see, thanks for the info. It occurred to me before co$$anonymous$$g back here, that your implementation is superior (I think) because if I ever want to clamp my rotation, I could run into a Gimbal Lock problem since I would need to go from Quats->Euler->Quats. Your way allows for clamping at the float level and then just one conversion from Eulers->Quats.

avatar image
0

Answer by Glurth · Feb 18, 2015 at 04:01 PM

I suspect the issue is that you are adjusting rotations around particular world axis (Quaternion.Euler). However, once you have rotated a bit on both axis, the WORLD axis is no longer what you want to rotate about: you want to rotate about the OBJECT'S current axis.

Take a look at using this function to modify your transforms rotation instead: http://docs.unity3d.com/ScriptReference/Transform.Rotate.html

Note that it has the option to rotate about a specified world space, or local space, axis. (default is local, which is what you want, I think)

EDIT: I think I'm going to delete this answer, i see now you ARE applying the rotation to the local object with *=

Comment
Add comment · Show 1 · 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 boddole · Feb 19, 2015 at 04:24 AM 0
Share

@Glurth: "i see now you ARE applying the rotation to the local object with *="

->Yeah, you and Rector (and myself) all seem to have come to the conclusion that just using some Transform.Rotate() method is just easier to work with...I just don't like it when I can't do something the way I would like to and cannot figure out why it doesn't work. Thanks for the effort though.

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

23 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

Related Questions

Flip over an object (smooth transition) 3 Answers

Help with rotating Camera around Pivotpoint(from A to B) 1 Answer

how do i take gyro rotation and multiply it? 1 Answer

how to clamp y axis with Quaternion.Euler in unity 1 Answer

RTS Camera movement wrong after rotation 1 Answer


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