• 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 Blyka · Mar 08, 2012 at 07:17 PM · camerarotationjavascriptmouse

"Perfect" Free Rotation Method? (like Blender)

I have a 3D object sitting alone in a scene, and I need the ability to freely and precisely rotate the view around it by way of the mouse (and eventually, the iPad's touch screen). If you happen to use Blender, what I need is exactly its method of rotating the camera around the model (middle mouse button in Windows). In Blender t$$anonymous$$s is done very smoothly; each click and drag works exactly as you would expect it to, with complete accuracy and control.

I've put in a fair amount of work in Unity trying to replicate t$$anonymous$$s effect, however I just can't get it to behave with such precision. The closest method I've found is by applying t$$anonymous$$s simple script directly to the object I wish to rotate:

 #pragma strict
 
 var speed : float = 550.0;
 var mx : float;
 var my : float;
         
 function Update() {
     if (Input.GetMouseButton(0))
     {
         mx = -Input.GetAxis("Mouse X");
         my = Input.GetAxis("Mouse Y");
         transform.Rotate(Vector3(my, mx, 0) * Time.deltaTime * speed, Space.World);
     }
 }

T$$anonymous$$s comes pretty close to what I'm looking for, however it feels too out of control; sometimes it moves in a way I wouldn't expect, and behaves oddly in some ways (e.g. if you click and swipe the mouse back and forth rapidly the model gradually rotates in a random direction, as opposed to accurately jumping back and forth to your mouse movements).

In following other scripts found here I've also tried rotating a camera around the object as opposed to rotating the object itself. The results felt a bit more precise than the above script, but were considerably more limiting (e.g. if you positioned the camera above the object so the top is facing you, you couldn't move it from side to side; it still appeared to spin on its Y axis).

I've searched through a lot of questions here relating to mouse-based rotation, but they have yet to produce the right effect, so I thought I'd ask myself. Anyone have any ideas how one might go about doing t$$anonymous$$s?

Comment
Add comment · Show 1
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 Blyka · Mar 13, 2012 at 06:06 PM 0
Share

After talking with my co-worker we decided my initial code will work for our needs- however I'm still very open to answers if anyone has more insight on how to achieve Blender's kind of camera rotation. Should I manage to figure it out myself down the road I'll be sure to update this with the solution.

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by apocriva · Mar 08, 2012 at 07:47 PM

What you probably want is somet$$anonymous$$ng like t$$anonymous$$s (disclaimer: I don't generally use JavaScript, and haven't actually tried t$$anonymous$$s code snippet live!):

 var speed : float = 550.0;
 var rotations : Vector3;
 
 function Update() {
     if (Input.GetMouseButton(0))
     {
        rotations.x = -Input.GetAxis("Mouse X") * Time.deltaTime * speed;
        rotations.y = Input.GetAxis("Mouse Y") * Time.deltaTime * speed;
        transform.localEulerAngles = rotations;
     }
 }

You might have to do some kind of normalization or somet$$anonymous$$ng, but the key is to have the rotations around the individual axes driven directly by the translation of the mouse (if that makes sense :)).

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 Blyka · Mar 09, 2012 at 06:30 PM 0
Share

Thanks for answering! I tried out your script, and after a bit of tweaking to get it working it seemed to apply the same effect as what I already had. From the sound of it I would have thought that having "the rotations around the individual axes driven directly by the translation of the mouse" was pretty much what the previous script was doing, but perhaps I'm misunderstanding.

avatar image
0

Answer by Owen-Reynolds · Mar 08, 2012 at 09:06 PM

I'm t$$anonymous$$nking the problem is diagonal motion. If I drag the mouse from lower-right to upper-left, it looks like (and makes sense) Blender is spinning the object around a (/)-looking axis (perpendicular to my motion.)

Rotating my hand, 90 degrees on x then 90 degrees global y (or local y) doesn't give the same effect. So, maybe use transform.RotateAround whenever you have X and Y motion together (the around line would be somet$$anonymous$$ng like (-Y,X).)

Also, you're going to get incremental errors if you always rotate from last frame -- all those little turns added up can drift the final result. A trick is to save the mouseDown spot, and each movement recompute from current pos to saved start pos.

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 Blyka · Mar 09, 2012 at 06:33 PM 0
Share

Thanks for your answer! I guess I should have mentioned I'm still fairly new to Unity (been at it intensely for just a few months now) so a few of those concepts went a bit over my head.

I tried using "transform.RotateAround" by replacing the "transform.Rotate" line with this:

transform.RotateAround(Vector3.zero, Vector3(my, mx, 0), Time.deltaTime * speed);

But it pretty much produced the same effect- only without taking mouse motion speeds into account. Am I misusing the function?

And I'm most interested in your advice on the incremental errors; I wonder if maybe you could elaborate on "why" all the little turns adding up can drift it? It seems to me like the script I provided should just work as far as that's concerned, so I'd be curious to know what's going wrong exactly.

For using your trick to fix that issue, I think I understand saving the mouseDown spot (the object's current rotation when you click?) but I can't think of how I would go about using that in relation to the rotation, as right now it's just based on the mouse motion as it happens.

Thanks again.

avatar image Owen-Reynolds · Mar 09, 2012 at 07:48 PM 0
Share

Rotating around a line that isn't the x, y or z axis is just a regular trig concept. Easy to find the math, but Unity has it also built-in. How to use RotateAround is obvious once you get the trig. The thing is, I'm pretty sure Rotate((mx,my)) isn't the same thing at all. So, if blender spins around diagonal lines, of course yours isn't the same.

Looking more at Blender, the camera is clearly moving, and it also depends on where you start (a Left to Right drag spins very different on top or bottom of the screen.) I can't say how blender works, now.

For the "amount from start" idea, you can look up the actual Mouse position (`Input.mousePosition`) and compute mx and my yourself. Depending on how you rotate, you may find out that spinRight + spinUp doesn't add to "spin diagonal right and up," so need this trick.

avatar image Blyka · Mar 13, 2012 at 06:05 PM 0
Share

Thanks a lot for the assistance, although most of it still goes over my head; calculating complex rotations in 3D space seems to be a whole separate issue from learning Unity's API, and I can't seem to wrap my head around it very well. @.@ Anyway, I really appreciate your time.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

6 People are following this question.

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

Related Questions

Camera Rotation 1 Answer

Mouse axes based on position, not movement. 1 Answer

Move the Object to Camera respective. 1 Answer

Rotate 3rd person Character according to mouse position 0 Answers

[JS]Rotate object y axis to mouse position 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