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
4
Question by krisventure · May 25, 2016 at 08:23 PM · rotationtransformbugscript errorplay mode

Very basic rotation BUG. transform.up = transform.up sets Y rotation to 0.

Okay I've nailed it all down to an issue that looks like a bug. To reproduce it, simply create any 3D objects eg. a cube in an empty project, set its Y rotation to anything else than 0, add a rigidbody and a new script. In the script's Start (or Update) method, simply write:

 transform.up = transform.up;

Obviously, this will change nothing, right? Wrong. If you view the cube falling from above, you'll see that its Y axis gets reset to 0 degrees as soon as you start Play Mode.

This issue is present for all axes. For example if I have an object traveling in direction Z, with a Z rotation different from 0, that Z rotation gets zeroed on startup if my scripts Update has:

 transform.forward = transform.forward;

This somehow then evolves into a more general problem, for example I can't keep my forward moving object's original Z angle, it gets zeroed just like above, as soon as I set the object to face the direction of its velocity with

 transform.forward = transform.GetComponent<Rigidbody> ().velocity; 

In my game, as the object that should at certain moments start to follow the direction of its own velocity is the parent to the first person camera, this means you'll see the camera view angle making instant rotations which looks awful.

Anyone knows if this is indeed a bug I should report or maybe there's something I'm missing that explains it?

Any workaround?

Comment
Add comment
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

1 Reply

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

Answer by Bunny83 · May 25, 2016 at 10:15 PM

This is not a bug. I was expecting someone bringing this up sooner or later ^^. The properties "up", "right" and "forward" return the objects local space axis. Unity also implements a setter for those properties. Of course when you set them Unity will create a rotation so that the given axis points along your given vector. However a single vector is not enough information to define a rotation in 3d.

Keep in mind that setting those properties do not perform some sort of "rotate towards" but it simply sets the absolute rotation. Imagine "forward" currently points to (0,0,1) so the object is not rotated at all. If you assign this vector (0,0,-1) to forward, what rotation do you expect? Did you mean to rotate around the y axis so up is still up? Or did you mean to rotate around the x axis so up becomes "-up" and the x axis remains? Unity could have implemented them as "choose a rotation that takes the shortest route from the current rotation", but even that wouldn't work in that example since both cases have the same distance.

That's why Quaternion.LookRotation actually takes two vectors as input. You can omit the second in which case it defaults to Vector3.up. This second "up vector" defines the rotation around the first vector. So by default when you use an arbitrary forward vector, the resulting rotation will be rotated so the objects up vector is as close as possible to the given up vector. That's also the reason why then looking straight down and rotate even further (over 90°) the view will flip 180°. So it's not possible to get the view upside down without providing a proper up vector to LookRotation.

Of course when you assign something to those properties you can't specify an additional reference vector so Unity always uses the default orientation as reference which is

 up      = Vector3.up
 forward = Vector3.forward
 right   = Vector3.right

Unity only provides a LookRotation method for the z axis. However you can use it for any other axis with a bit of logic. Say you want to set the up vector to point along a certain vector (targetUp). You can simply use:

 transform.rotation = Quaternion.LookRotation(targetUp, -transform.forward);

This will make your object to look straight up along your desired up direction. Now you just need to rotate 90 downwards to get your final rotation. For this you need to rotate around the right axis 90°

 transform.Rotate(Vector3.right, 90f);

So those two lines will be the same as setting the up vector to a certain vector but it tries to keep the old forward axis.

If you want to set a new forward and want to keep the last up vector you would simply do:

 Vector3 targetDir = transform.GetComponent<Rigidbody> ().velocity;
 transform.rotation = Quaternion.LookRotation(targetDir, transform.up);


Comment
Add comment · Show 7 · 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 krisventure · May 25, 2016 at 11:33 PM 0
Share

Thank you Bunny83, I'm new to the Unity forum but I swear it's the first time in my life that someone actually answered (and solved) a question I've posted on any Q&A forums, maybe my questions are just weird lol. I was about to press the Send bug report button when I saw your answer. I was like that can't be normal that x=x makes any difference but hell yeah there's an explanation! Funny thing I'd tried almost this exact line before but I wrote Quaternion.LookRotation(targetDir, Vector3.up) which had the same issue so I gave up on it. Well I guess that's the benefit when you understand all these quaternions inside out! Thanks again, and especially for the detailed explanation, a deep insight into Unity's $$anonymous$$d :)

avatar image Owen-Reynolds krisventure · May 26, 2016 at 04:03 AM 0
Share

Just FYI, it's not a Unity thing -- just standard geometry and program$$anonymous$$g. It's also a commonish Q here. Googling "Unity set transform.up" gives a few older questions and answers.

avatar image krisventure Owen-Reynolds · May 26, 2016 at 10:15 AM 0
Share

You're right @Owen Reynolds I've found something similar here although it only reports the issue in a specific context so the answer there isn't as generally explained as that of bunny83: http://answers.unity3d.com/questions/138173/cant-understand-why-object-rotates-when-setting-tr.html

Naah, this isn't just standard geometry and program$$anonymous$$g, Unity has its own way of handling it as @Bunny83 points it out. They could make the transform.up.Set method require a 2nd rotation parameter as well, for instance that avoids such confusions, maybe even disable the setting of up forward and right by direct assignment (and allowing only by a 2 param setter method) considering the uncertainty introduced by assigning a direction to it without specifying a rotation. There could be other, probably better ways to handle it by program$$anonymous$$g standards. And things like transform.up = transform.up sets the Y rotation are just contraintuitive, could be taken care of by an if statement or a warning.

In fact the most intuitive way to do it would be like this: when I use transform.up = targetDir, ins$$anonymous$$d of setting Y rotation to default, just automatically assign whatever rotation leaves Y unchanged. User hardly ever wants the way it is now, he just wants to set his object's up direction and preserve its local Y rotation. Or set its forward and preserve the local Z rotation. Or set its right dir and preserve local X rotation.

Show more comments
avatar image Bill-Sansky · Apr 14, 2018 at 08:07 PM 0
Share

Thank you for your detailed and very easy to follow explanation, you rock!

avatar image M_1t · Sep 11, 2019 at 07:39 PM 0
Share

Thank you my friend. You are a true hero.

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

8 People are following this question.

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

Related Questions

[Solved] Quaternion from IMU sensor to GameObject Orientation problem 3 Answers

Unity Bug? Parent object rotates around child object. 1 Answer

Quaternion rotation issue please help :'( 0 Answers

Create Field of vision 1 Answer

Clamping rotation between two angles 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