Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 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 Oorlfe · Jul 31, 2015 at 09:15 AM · rotationpositionunparenting

Why is rotation and unparenting causing discrepancy between visual position and Inspector? Not a local vs global position confusion.

Hi,

In my scene I have two 1x1x1 unity cubes. The first, "cube", is at (0,0,0). The second, "cube1", is at (0,1,0). Both are tagged "Cube" and start in an empty parent object called "cubes". My script parents them in an empty game object positioned at (0,.5f,0), rotates that around the x axis 90 degrees after key input and then unparents them.

The problem starts after odd numbers of 90 degree rotations, even works great. User hits the key, the cubes are parented. The parent rotates 90 degrees. The cubes are unparented. Everything is visually in place and the Inspector has only a very tiny discrepancy. "cube" is at (0,.5,-.5) and "cube1" is at (0,.499,5). As small as the shift from .5 is it seems to makes all the difference. The cubes are parented again, the parent rotates, the cubes are unparented. Again, visually, everything is fine, the cubes appear to be in the expected places and "cube's" position in the Inspector is even as expected (0,1,0), but "cube1's" position in the inspector is (0,-1.192,0) which visually it is definitely not at. Also, when I attempt to adjust the y position, in the Inspector, for "cube1" at this point the number snaps to 0 as if it had been there all the time. After many rotations everything starts to break down.

It always starts with that tiny shift after an unparenting following an odd number of spins. unparenting after an even number of spins is no problem, everything still works great. Also, if I do not unparent the cubes at all everything works great. If this script was all I was trying to do I could just stop unparenting them, but it is a part of a larger script that requires cubes to be changing parents. Changing parents without unparenting first seems to cause the same effect.

Thanks in advance for any help.

 using UnityEngine;
 using System.Collections;
 
 public class RotTester : MonoBehaviour 
 {
     private GameObject[] cubes;
 
     private GameObject pivot;
     private GameObject endRotation;
 
     private bool rotate;
     
     private float t;
     private float c;
 
     void Start () 
     {
         rotate = false;
         t = 0;
 
         endRotation = new GameObject ("endRotation");
 
         pivot = new GameObject ("pivot");  
         pivot.transform.position = new Vector3 (.5f, .5f, 0);
 
         cubes = GameObject.FindGameObjectsWithTag ("Cube");
     }
 
     void Update () 
     {
         if (Input.GetKeyDown(KeyCode.Q))
         {
             foreach (GameObject cube in cubes) 
             {
                 cube.transform.parent = pivot.transform;
             }
             
             endRotation.transform.Rotate (Vector3.right, 90, Space.World);
             rotate = true;
         }
 
         if (rotate == true) 
         {
             pivot.transform.rotation = Quaternion.RotateTowards (pivot.transform.rotation, endRotation.transform.rotation, Time.deltaTime * 400);
 
             if (t < 1) 
             {
                 t += Time.deltaTime;
             } else 
             {
                 foreach(GameObject cube in cubes)
                 {
                     cube.transform.parent = null;
                 }
                 
                 t = 0;
                 rotate = false;
             }
         }
     }
 }

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 AlwaysSunny · Jul 31, 2015 at 09:15 AM 0
Share

Always format your code with 101010 button or your questions will be rejected. This has been done for you this time. ;)

avatar image AlwaysSunny · Jul 31, 2015 at 09:22 AM 1
Share

Diagrams and videos really help in these situations. I'm also not sure exactly what the problem is - phrases like "breaks down" don't communicate anything meaningful. In what way does this problem manifest besides observing incorrect values in the inspector?

I don't have a clear picture of what you're communicating, but you appear to be confident that the problem has something to do with the floating point imprecision you mention.

$$anonymous$$aking some major assumptions about your game's nature, you could try a hack-y fix: At whatever moment is most convenient, such as immediately before the problem would otherwise manifest, snap the position components to the nearest "good" increment.

 value = $$anonymous$$athf.Round(value / 0.5f) * 0.5f;
avatar image Owen-Reynolds · Aug 01, 2015 at 02:48 AM 1
Share

Is the number (if you click and scroll in the space) really maybe -1.192xxxxx e-10 ?

2 Replies

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

Answer by DiegoSLTS · Aug 01, 2015 at 03:22 AM

If you make the Inspector window wider you'll see that "-1.192" is not the whole value on that field, it probably is something like "-1.192E-20", which means... a really small number. Something similar goes for the 0.499 value, it probably is 0.499999... In practice is the same as 0.5.

Unity does some math when you do rotations, translations and parenting/unparenting (usually a product of a vector and a matrix), and those operations produce some errors inherent of the limited precision of floats.

If you really need those values to be exactly "0.5" or "0" you have to assign them manually (in the inspector or through a script), you can't expect Unity to assign rounded values.

Comment
Add comment · Show 2 · 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 Bunny83 · Aug 01, 2015 at 04:59 AM 0
Share

Yep, i thinks that's the case ^^. Btw, just to illustrate what "-1.192E-20 actually looks like:

 -0.00000000000000000001192

If you don't know that the scientific notation is you might want to look it up ^^.

avatar image Oorlfe · Aug 02, 2015 at 08:11 AM 0
Share

Thank you everyone for the responses.

AlwaysSunny, I will remember that about the 101010, thanks. What I meant by "break down" was that the more the rotations and unparenting the greater the floating point imprecision becomes until eventually the cubes move into each other.

Owen Reynolds and DiegoSLTS, You are absolutely right, that is the case. I am familiar with scientific notation, but I did not realize that was happening here, thanks.

Great to know its something I'll have to assign the values another way.

Unfortunately, I don't think this is the cause of the problem I'm having in my larger script anymore. I'll post a new question about it in detail, but to sum it up I am making a rubik's cube type of thing, 3x3x3, using a similar code to the one in this post. The columns all work great, but when I add rotation to the rows the parents are no longer collecting all 9 cubes after odd numbers of rotations. When I noticed the issue I asked about in this post I'd hoped it might indicate something else I didn't understand that would be the key, but its not looking that way. The method of collection I'm using follows:

 foreach (GameObject cube in cubes) 
         {
             if (cube.transform.position.x == 2) 
             {
                 cube.transform.parent = rightPivot.transform;
             }
         }

Some of the cubes not being collected aren't having the floating point imprecision issue.

Thanks again! Any ideas about this one I'd love to hear.

avatar image
1

Answer by Baste · Aug 02, 2015 at 12:13 PM

Don't rely on delta movements/rotations when you need exact possitions.

As the other commenters have pointed out, what's happening is that you get really small errors due to floating point rounding errors. These are inevitable - floats are implemented as numbers on the form (a * (2 ^ b)), so exact representations of most numbers are not possible.

So whenever you rotate something X degrees, there's a good chance that you're not rotating it exactly X degrees, but something very close to it. The small error isn't a problem when you only rotate once, but when you get many of those errors, the problem grows.

The solution is to not use delta rotations - ie. not add rotations together. So if you have rotated 90 degrees, and want to rotate 90 more degrees, don't add 90 to your rotation, but set it directly to 180.

If you're implementing a Rubiks Cube, each of the eight rotation bases has exactly 4 possible rotations. You can find those on start, store them, and then rotate towards the next one whenever the player rotates one of them. In addition, you could store the relative possition the cubes should have, and move the current child-cubes to those locations after a rotation, to compensate for rounding errors.

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 Oorlfe · Aug 03, 2015 at 09:42 PM 0
Share

Thanks Baste!

That was very helpful. $$anonymous$$y cube is working great now.

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Unable to set Rotation 1 Answer

Converting www.text or string to rotation or position 2 Answers

Calculating a new position based on where another object is facing 1 Answer

Add an offset to the position of an object in front of it 1 Answer

How can I identify a non-uniform scaled mesh, and fix it? 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