Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Quaternion problem

Discussion in 'Scripting' started by ElFab, Nov 8, 2017.

  1. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    Hello, i'm having problem trying to lerp quaternion. I have a func that lerp x,y,z,w in a quaternion in order to make rotate a transform. my probleme is that when the quaternion is changed by a little value it simply doesn't take it.
    exemple :
    Code (csharp):
    1.  
    2.  
    3. Quaternion value = mYfunc(transformToMove.rotation,target.rotation, someSeetings...);
    4. Debug.Log("calculated : "+value.x + " "+value.y + " "+value.z + " "+value.w)
    5. transformToMove.rotation = value;
    6. Debug.Log("affected : "+transformToMove.rotation.x + " "+transformToMove.rotation.y + " "+transformToMove.rotation.z + " "+transformToMove.rotation.w)
    7.  
    8.  
    9. output:
    10. calculated 0 0.87545 0 -0.4558
    11. affected    0 0.89243 0 -0.4732
    12.  
    so at next update my calcul is based on the new value of the transform.rotation wich is something same than what it was last time... my object don't turn anymore. Something i don't understand is that if i turn slowly the "target" (when this bug is here), the quaternion turn at same rate but in the reverse direction if i change it at a high rate, the bug desapear...

    Most of the time i have no problem, but sometimes this problem occurs and i don't understand why, at a time, i though that some values was not Quaternion compatible, is it the case?
     
  2. UziMonkey

    UziMonkey

    Joined:
    Nov 7, 2012
    Posts:
    206
    As a general rule of thumb you should not be touching the components of a quaternion. They are very complex things and its best to stick to the API.

    Also, you should not be lerping a quaternion, you should be using the Quaternion.Slerp method.
     
    JoeStrout likes this.
  3. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    I don't want to use this because target is able to move or change and i don't want to stop my rotation if this happened.
    It's not realy a Lerp, it's a go to with acceleration, maxspeed, deceleration and inertie.
     
  4. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    As in lerping the x,y,z,w values individually? Yeah, don't do that. You may be breaking the quaternion (it might no longer be a unit quaternion, for one thing...)

    As suggested above, use Quaternion.Slerp instead.
     
    lordofduct likes this.
  5. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    OK but the point still stands: Don't touch any of the x,y,z,w values unless you know what you are doing (i.e. you have a very good understanding of quaternion math, understand they are complex numbers, etc.)
     
  6. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    yes i saw that somewhere^^ and no i don't know what i am doing :p... But i don't know how to do what i want in an other way. my func work, but bug sometime, . It's why i'm here, if someone know why this happen or have an other way to do what i want.
    Before to wrote this func, i thought i should have something very bad while in transition, but that's not the case, unless i move more than one axe. And when moving more than one axe that's not too bad and give something uncontroled but nice in my disign. I should apreciate to solve this problem in an other way than "don't touch that"^^. But if i must, i'll do it ( i already did it bit i was unable to controle the time, speed etc...), for now i prefere keep it in state and wait for someone knowing Quaternion.

    I change all of the values from position to destination and that work (almost^^)
     
    Last edited: Nov 8, 2017
  7. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Use Quaternion.RotateTowards().
     
  8. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    You should have a look at the Quaternion documentation. There's a whole bunch of helper functions in there to help you with common Quaternion problems.

    As mentioned above, if Lerp/Slerp isn't what you want, then Quaternion.RotateTowards() is probably what you want. You set a maximum angle to rotate by, which should give you more control over acceleration, inertia, etc.
     
  9. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    I already did it, more than one time since i'm working around problems with angles... something not easy for me. Yes Quaternion.RotateTowards() was the first think i did after put eulerAngles to trash, but the problem is that : How to continue to Rotate "bewtween" two target. I want to say the folowing : not easy to explain with rotation but i'll try.
    1 - My object is standing
    2- My object got a rotation target (1)
    3 - it start to turn, accelering, calculating his speed etc and then
    4 - he got a new target (2), i don't want my object go directly in the direction of target 2,
    I want it to continu in his rotating movement while slowly changing to go to target 2, it's what i have with my code, and it's what i want. the only problem is that sometime when i do change the value of the transform.rotation, it's not changing anything, and it's what i want to understand why.

    Maybe i can simulate that using something that can make a weighted average of quaternions (sound not fine i don't know why) or make two following rotateToward(), but at this moment i just want to understand why the value isn't changed.

    When the bug is here, i can feel something like repulsing strengh (like magnet strengh), if i don't set a maxspeed, the rotation is braked but with the increasing speed, the rotation pass the "stiff points". It's like if the value was not existing in the quaternion spectrum.
     
    Last edited: Nov 8, 2017
  10. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    Soo, i did the stuf while only using API, as all of you sayd :).
    And yes that work as intended. I pose the code here if someone need it :

    Code (csharp):
    1.  
    2.  
    3. public static class MoveUtility
    4. {
    5.     public class QuaternionData
    6.     {
    7.         public Quaternion target;
    8.         public List<float> speed = new List<float> { 0 };
    9.         public bool isFree = false;
    10.  
    11.         public QuaternionData(Quaternion target)
    12.         {
    13.             this.target = target;
    14.         }
    15.     }
    16.  
    17.     public static Quaternion AdvancedLerp(Quaternion from,Quaternion to, float acc, float dec,float maxSpeed, Dictionary<Quaternion,QuaternionData> quatDatas, float time)
    18.     {
    19.         Quaternion toReturn = from;
    20.         List<Quaternion> toRemove = new List<Quaternion>();
    21.         if (!quatDatas.ContainsKey(to))
    22.             quatDatas[to] = new QuaternionData(to);
    23.  
    24.         foreach (QuaternionData quaternionData in quatDatas.Values)
    25.         {
    26.             if (quaternionData.target == to)
    27.                 quaternionData.isFree = false;
    28.             else
    29.                 quaternionData.isFree = true;
    30.             float angle = Quaternion.Angle(from, quaternionData.target);
    31.             Vector3 zero = Vector3.zero;
    32.             Debug.Log("staying Angle: " + angle);
    33.             float newAngle = AdvancedLerp( 0 , angle , acc, dec, maxSpeed, quaternionData.speed , Time.deltaTime,false, quaternionData.isFree);
    34.             Debug.Log("newAngle: " + newAngle);
    35.             toReturn = Quaternion.RotateTowards(toReturn, quaternionData.target, newAngle);
    36.             if (newAngle == 0 && to != quaternionData.target)
    37.             {
    38.                 toRemove.Add(quaternionData.target);
    39.             }
    40.  
    41.         }
    42.         foreach (var item in toRemove)
    43.         {
    44.             quatDatas.Remove(item);
    45.         }
    46.  
    47.  
    48.         return toReturn;
    49.     }
    50.  
    51.     public static Vector3 AdvancedLerp(Vector3 currentvalue, Vector3 endvalue, float acc, float _deceleration, float maxSpeed, List<float> currentspeed, float time)
    52.     {
    53.         List<float> _currentValue = new List<float>() { currentvalue.x, currentvalue.y, currentvalue.z };
    54.         List <float> _endValue = new List<float>() { endvalue.x, endvalue.y, endvalue.z };
    55.         List<float> _result = AdvancedLerp(_currentValue, _endValue, acc, _deceleration, maxSpeed, currentspeed, time);
    56.         return new Vector3(_result[0], _result[1], _result[2]);
    57.     }
    58.  
    59.     public static float AdvancedLerp(float currentvalue, float endvalue, float acc, float _deceleration, float maxSpeed, List<float> currentspeed, float time, bool givenEndValue = true, bool freeit = false)
    60.     {
    61.         List<float> _currentValue = new List<float>() { currentvalue };
    62.         List<float> _endValue = new List<float>() { endvalue };
    63.         return AdvancedLerp(_currentValue, _endValue, acc, _deceleration, maxSpeed, currentspeed, time,givenEndValue, freeit)[0];
    64.     }
    65.  
    66.     private static List<float> AdvancedLerp(List<float> currentvalue, List<float> _endvalue, float acc,float _deceleration, float maxSpeed, List<float> currentspeed,float time, bool givenEndValue = true, bool freeit = false)
    67.     {
    68.         List<float> toReturn = new List<float>();
    69.         for (int i = 0; i < currentvalue.Count; i++)
    70.         {
    71.             float distanceToEnd = 0;
    72.             float endvalue = 0;
    73.             if (givenEndValue)
    74.             {
    75.                 distanceToEnd = _endvalue[i] - currentvalue[i];
    76.                 endvalue = _endvalue[i];
    77.             }
    78.             else//endValue is not the position at end but the distance left to the end.
    79.             {
    80.                 distanceToEnd = _endvalue[i];
    81.                 endvalue = _endvalue[i] + currentvalue[i];
    82.             }
    83.             if (freeit)
    84.             {
    85.                 if (Mathf.Abs(currentspeed[i]) < _deceleration * time)
    86.                 {
    87.                     currentspeed[i] = 0;
    88.                  
    89.                 }
    90.                 else
    91.                 {
    92.                     if (currentspeed[i] > 0)
    93.                     {
    94.                         currentspeed[i] = currentspeed[i] - _deceleration * time;
    95.                     }
    96.                     else
    97.                     {
    98.                         currentspeed[i] = currentspeed[i] + _deceleration * time;
    99.                     }
    100.                 }
    101.  
    102.                 toReturn.Add(currentvalue[i] + currentspeed[i] * time);
    103.                 continue;
    104.             }
    105.  
    106.             float mindist = acc * Mathf.Pow(time, 2) / 2;
    107.             if (mindist > Mathf.Abs(distanceToEnd))
    108.             {
    109.                 currentspeed[i] = 0;
    110.                 toReturn.Add(endvalue);
    111.                 Debug.Log("One Terminated");
    112.                 if (toReturn.Count == currentvalue.Count)
    113.                     Debug.Log("All Terminated");
    114.                 continue;
    115.             }
    116.             float inertie = ((Mathf.Pow(currentspeed[i], 2) / _deceleration) / 2);
    117.             if (currentspeed[i] < 0)
    118.                 inertie = -inertie;
    119.  
    120.             Debug.Log("distanceToEnd : "+ distanceToEnd + "  <?  inertie: "+ inertie + "  =>  " + Mathf.Sqrt(Math.Abs(distanceToEnd * 2 * _deceleration)));
    121.             if (distanceToEnd > 0)
    122.             {
    123.                 if (inertie >= distanceToEnd)
    124.                     currentspeed[i] = Mathf.Sqrt(distanceToEnd * 2 * _deceleration);
    125.                 else
    126.                 {
    127.                     if (currentspeed[i] > 0)
    128.                     {
    129.                         currentspeed[i] = currentspeed[i] + acc * time;
    130.                     }
    131.                     else
    132.                     {
    133.                         currentspeed[i] = currentspeed[i] + _deceleration * time;
    134.                     }
    135.                 }
    136.             }
    137.             else
    138.             {
    139.                 if (inertie <= distanceToEnd)
    140.                     currentspeed[i] = -Mathf.Sqrt(-distanceToEnd * 2 * _deceleration);
    141.                 else
    142.                 {
    143.                     if (currentspeed[i] < 0)
    144.                     {
    145.                         currentspeed[i] = currentspeed[i] - acc * time;
    146.                     }
    147.                     else
    148.                     {
    149.                         currentspeed[i] = currentspeed[i] - _deceleration * time;
    150.                     }
    151.                  
    152.                 }
    153.             }
    154.  
    155.             if (Math.Abs(currentspeed[i]) > maxSpeed)
    156.             {
    157.                 if (currentspeed[i] < 0)
    158.                     currentspeed[i] = -maxSpeed;
    159.                 else
    160.                     currentspeed[i] = maxSpeed;
    161.             }
    162.             Debug.Log("current speed : "+currentspeed[i]);
    163.             toReturn.Add(currentvalue[i] + currentspeed[i] * time);
    164.         }
    165.         return toReturn;
    166.  
    167.     }
    168. }
    169.  
    170. public static class TransformPosition
    171. {
    172.     /// <summary>
    173.     /// Vitesse general des animations, default : 100.
    174.     /// </summary>
    175.     public static float GeneralAnimSpeed = 100;
    176.  
    177.     private class Animation
    178.     {
    179.         public Setting setting;
    180.         public Transform startPosition;
    181.         public Transform transformToMove;
    182.         public Transform endPosition;
    183.         public List<float> velocityPos = new List<float>() { 0, 0, 0 };
    184.         public Dictionary<Quaternion, MoveUtility.QuaternionData> velocityRot = new Dictionary<Quaternion, MoveUtility.QuaternionData>();
    185.  
    186.         public Animation(Transform transformToMove, Transform endPosition,Setting setting)
    187.         {
    188.             if (startPosition == null)
    189.                 startPosition = new GameObject().transform;
    190.             startPosition.position = transformToMove.position;
    191.             startPosition.rotation = transformToMove.rotation;
    192.  
    193.             this.transformToMove = transformToMove;
    194.             this.endPosition = endPosition;
    195.             this.setting = setting;
    196.         }
    197.  
    198.         public void Update()
    199.         {
    200.             transformToMove.position = MoveUtility.AdvancedLerp(transformToMove.position
    201.                                                                 , endPosition.position
    202.                                                                 , setting.posAcc
    203.                                                                 , setting.posDec
    204.                                                                 , setting.posMaxSpeed
    205.                                                                 , velocityPos
    206.                                                                 , setting.posGeneralSpeed * GeneralAnimSpeed / 10000 * Time.deltaTime);
    207.  
    208.             transformToMove.rotation = MoveUtility.AdvancedLerp(transformToMove.rotation
    209.                                                             , endPosition.rotation
    210.                                                             , setting.rotAcc
    211.                                                             , setting.rotDec
    212.                                                             , setting.rotMaxSpeed
    213.                                                             , velocityRot
    214.                                                             , setting.rotGeneralSpeed * GeneralAnimSpeed / 10000 * Time.deltaTime);
    215.         }
    216.     }
    217.     private static Dictionary<Transform, Animation> animations = new Dictionary<Transform, Animation>();
    218.  
    219.     public static void Update()
    220.     {
    221.         foreach (Animation item in animations.Values)
    222.         {
    223.             item.Update();
    224.         }
    225.     }
    226.     public static void SetDestination(Transform transformToMove, Transform endPosition,Setting setting)
    227.     {
    228.         animations[transformToMove] = new Animation(transformToMove, endPosition, setting);
    229.     }
    230.     public class Setting
    231.     {
    232.         public static Setting normal = new Setting(rotMaxSpeed:50);
    233.  
    234.         public float posGeneralSpeed;
    235.         public float rotGeneralSpeed;
    236.         public float posAcc;
    237.         public float posDec;
    238.         public float posMaxSpeed;
    239.         public float rotAcc;
    240.         public float rotDec;
    241.         public float rotMaxSpeed;
    242.  
    243.         public Setting(float posGeneralSpeed = 100, float rotGeneralSpeed = 100, float posAcc = 100, float posDec = 100, float posMaxSpeed = 100, float rotAcc = 100, float rotDec = 100, float rotMaxSpeed = 100)
    244.         {
    245.             this.posGeneralSpeed = posGeneralSpeed;
    246.             this.rotGeneralSpeed = rotGeneralSpeed;
    247.             this.posAcc = posAcc;
    248.             this.posDec = posDec;
    249.             this.posMaxSpeed = posMaxSpeed;
    250.             this.rotAcc = rotAcc;
    251.             this.rotDec = rotDec;
    252.             this.rotMaxSpeed = rotMaxSpeed;
    253.         }
    254.     }
    255. }
    256.  
    Base settings are not armonised yet but it's the easy part.
    You can use this like that :
    Code (csharp):
    1.  
    2.             //this is the general speed of all your animations;
    3.             TransformPosition.GeneralAnimSpeed = 130;
    4.  
    5.             //this is a setting for your animations
    6.             TransformPosition.Setting setting = new TransformPosition.Setting(posMaxSpeed : 35);
    7.             //setting contain the folowing :
    8.             //public float posGeneralSpeed; default : 100;
    9.             //public float rotGeneralSpeed;   default : 100;
    10.             //public float posAcc;                   default : 100;
    11.             //public float posDec;                   default : 100;
    12.             //public float posMaxSpeed;        default : positiveInfinity;
    13.             //public float rotAcc;                     default : 100;
    14.             //public float rotDec;                    default : 100;
    15.             //public float rotMaxSpeed;         default : positiveInfinity;
    16.  
    17.             //this is how to create a new animation with your setting:
    18.             TransformPosition.SetDestination(ObjectToMove.transform, target.transform, setting);
    19.  
    20.             //or use your pre-made settings :
    21.             TransformPosition.SetDestination(ObjectToMove2.transform, target.transform, TransformPosition.Setting.exemple);
    22.  
    23.  
    24.  
    But the question is here yet, why this magnet effet on quaternion while manipulating x,y,z,w values???
     
    Last edited: Nov 9, 2017
  11. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,924
    This won't affect the best advice, which is "use the quaternion built-in functions," but the specific Q is about how values in the same quaternion can magically change when no-one changed them.

    I'm guessing the issue is that transform.rotation=value; isn't a simple assignment. It's probably "normalizing" the quaternion as well. Which means Yfunc created a wrong quaternion, which is allowed(*) (that's why we see the numbers when printing _value_) But the assignment statement fixes the numbers before it goes into our rotation.
     
  12. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    Yes something like that, but what is the restriction? What in within the assignement say : no that's not a good value i don't want it? I'm now a little interested by quaternion and will learn more about them.
     
  13. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,924
    Th only thing you need to know about how quaternions work is that calculus is much easier. People used to use quaternions for normal math. When calculus was invented they switched to it, since quaternions were so much worse to use. We later rediscovered them for rotations.
     
  14. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    Happy to hear that! :D

    Don't forget that Vector3 also has helper functions you can use in addition to Quaternions. Vector3.SignedAngle might be of particular interest.
     
  15. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    This seems quite possible. I don't have access to the full source code, but the decompiled code seems to look like this:

    Code (csharp):
    1.  
    2. public Quaternion rotation
    3. {
    4.   get
    5.   {
    6.     Quaternion result;
    7.     this.INTERNAL_get_rotation(out result);
    8.     return result;
    9.   }
    10.   set
    11.   {
    12.     this.INTERNAL_set_rotation(ref value);
    13.   }
    14. }
    15.  
    We see that rotation is actually a property and it's possible that the internal code does some normalizing.
     
  16. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,924
    I just realized how easy it was to test whether setting a rotation does extra math. Try the OP's code but replace the first line with: Quaternion value = new Quaternion(1,2,3,4);

    You get back (1,2,3,4) in line one. But (0.2, 0.4, 0.5, 0.7) after copying to the rotation.

    In theory, the getting could be doing the extra math. But that seems like an odd way to do the same thing.
     
  17. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,878
    You shouldnt break up a Quarternion into its seperate components, a Quarternion (in the unity usage in terms of rotations) is the rotation column of a transformation matrix, and it is a unit Quarternion (Versor) usually meaning it only goes from 0-1. A transformation is a complex bit of math and if you want to break it up, you need to recreate the entire matrix.

    For more information on how to do this, and to learn more about quarternion and matrix math from a unity c# point of view, check out:

    http://catlikecoding.com/unity/tutorials/rendering/part-1/
     
    LiterallyJeff likes this.
  18. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    MadeFromPolygons likes this.
  19. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    Crazy, thanks for the link.
     
  20. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,924
    Just to be clear, there's no reason to learn or use matrixes in order to use Unity. Learning to use quaternion angleAxis, Euler, Slerp ... . is all you need.

    The graphics card uses matrixes, which means the camera in Unity uses one, but it does all the work. I haven't needed to touch a matrix in Unity for years. And they won't really help you understand rotations. The real use of a matrix is combined rotation/translation/scaling. In Unity we set those the regular way, in the transform, and let the system handle it.

    If you enjoy math, rotation matrixes are real math matrixes. They also involve some fun trig. Playing with them is pretty fun if you enjoy math for the sake of math.
     
    MadeFromPolygons likes this.
  21. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    it's just interesting and i'm curious
     
    MadeFromPolygons likes this.
  22. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,878
    Owen is of-course entirely right!

    I personally have used unity professionally for nearly 5 years now, and have been using it as a hobbyist for 8ish Years or so, and I only learnt that math this year!

    So yes, its fun to understand the deep workings, but unnecessary!
     
  23. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    Hello, i'm back with a similar problem but with position :
    Code (csharp):
    1.  
    2.             Vector3 test = MoveUtility.AdvancedLerp(transformToMove.position
    3.                                                     , EndPosition.position
    4.                                                     , Setting.posAcc
    5.                                                     , Setting.posDec
    6.                                                     , Setting.posMaxSpeed
    7.                                                     , animData.velocityPos2
    8.                                                     , Setting.posGeneralSpeed * GeneralAnimSpeed / 10000 * Time.deltaTime
    9.                                                     , animData.isFree);
    10.             Debug.Log("Before :   "+ test.x + "   " + test.y + "   " + test.z);
    11.             transformToMove.position = test;
    12.             Debug.Log("Ater :  " + transformToMove.position.x + "   " + transformToMove.position.y + "   " + transformToMove.position.z);
    13.  
    14. //Result :
    15. //Before :  -193   173   0
    16. //After :   -193   173   -7.152557E-06
    17.  
    18.  
    That make me crazy. (And 5hour more lost for found that...)
     
  24. nat42

    nat42

    Joined:
    Jun 10, 2017
    Posts:
    353
    -0.000007 is close to 0
     
  25. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    For now i'll use this for know if the target is reach but that seam not clean... If someone know something about that, there is a reason but i don't know it soo i cannot do that not happen.
    Code (csharp):
    1.  
    2.            if(Math.Abs((transformToMove.position - EndPosition.position).magnitude) < 0.001 && Quaternion.Angle(transformToMove.rotation, EndPosition.rotation) < 0.01)
    3.             {
    4.                 return true;
    5.             }
    6.  
     
  26. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    Yes it's close but how do i test the equality? how much distance should i compare, should i be sure that 0.001 is enough for that never happen? it's that the problem
     
  27. nat42

    nat42

    Joined:
    Jun 10, 2017
    Posts:
    353
    If the units are metres then 0.001 is 1mm, or going one more decimal place 0.0001 is the width of a hair... how close do you need it to be?

    EDIT: Fun fact 0.000007 metres is about the width of a single bacteria cell
     
    Last edited: Nov 12, 2017
  28. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    I just want to understand, and i don't like to do what i did for solve the problem, it's not a clean solution, just a temporary one (i'll found an other way). And if the only one which compare position vs vector and have probleme is me, soo it's that i do something bad...
     
  29. ElFab

    ElFab

    Joined:
    Sep 20, 2017
    Posts:
    37
    In fact, i think to a reason about why this happen, the object is a child of a gameobject, maybe the position is first calculate in local value, and a light round is done (or a math error), then when we read the world value ( maybe one more error here), that's not exactly the same that what we entered. Is anyone can confirm that, and if it's that, do you know how much is the max difference we can have or do you know more about calculation precision?
     
  30. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    Looks like that's just the nature of floating points to me. You can only have so many digits before you start losing precision with floats. Use Mathf.Approximately to compare floats.
     
  31. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,924
    Hmmm. In practice you usually want to change the localPosition of a child (instead of the position.) That's usually why you made it a child.

    As far as floating points and rounding, any Intro to Computer Programming book will cover it. Or google the term. I like chapter 20 of the "Intro to Programming" section on the taxesforcatses site. But people have been explaining floating points since the internet existed.

    Yes, it probably is because it's a child, so setting position actually runs some math in that case.