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. Dismiss Notice

Unwanted and inexplicable offset!

Discussion in 'Scripting' started by ecv80, Apr 24, 2020.

  1. ecv80

    ecv80

    Joined:
    Oct 1, 2017
    Posts:
    28
    Hi,

    I'm moving some of my objects like this:

    transform.position += transform.right * dT * speed;


    where speed is a given variable and dT is Time.deltaTime

    Strangely enough (and after a good while I admit), I've noticed transform.position.z incrementing by a small fraction too!

    I tried the following in the debugger:
    Code (CSharp):
    1. transform.right
    2. {(-1.0, 0.0, 0.0)}
    3.  
    4. transform.position
    5. {(-142.4, 0.5, 7968.2)}
    6. magnitude: 7969,446
    7. normalized: (0.0, 0.0, 1.0)
    8. sqrMagnitude: 6,351206E+07
    9. x: -142,3741
    10. y: 0,5000076
    11. z: 7968,174
    12. Static members:
    13.  
    14. transform.position+=transform.right*dT*speed
    15. {(-149.4, 0.5, 7968.2)}
    16. magnitude: 7969,573
    17. normalized: (0.0, 0.0, 1.0)
    18. sqrMagnitude: 6,35141E+07
    19. x: -149,3545
    20. y: 0,5000076
    21. z: 7968,174
    22. Static members:
    23.  
    24. transform.position+=transform.right*dT*speed
    25. {(-156.3, 0.5, 7968.2)}
    26. magnitude: 7969,709
    27. normalized: (0.0, 0.0, 1.0)
    28. sqrMagnitude: 6,351627E+07
    29. x: -156,3348
    30. y: 0,5000076
    31. z: 7968,176
    32. Static members:
    33.  
    34. transform.position+=transform.right*dT*speed
    35. {(-163.3, 0.5, 7968.2)}
    36. magnitude: 7969,851
    37. normalized: (0.0, 0.0, 1.0)
    38. sqrMagnitude: 6,351853E+07
    39. x: -163,3152
    40. y: 0,5000076
    41. z: 7968,178
    42.  
    See what's going on with Z? You can only see this in the debugger when you unfold the object details for higher precision.

    I know floating point math is not exact, but isn't this too much deviation? The effect is pretty obvious in my game after a while.

    Is this not the right way to move transforms? For the moment I'm going to change it to
    transform.position=new Vector3(transform.position.x+dT*speed, transform.position.y, transform.position.z)

    But can you explain what's going on here? Thoughts?

    Thank you
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,741
    What is transform.rotation? Is it precisely 0,0,0?
     
  3. ecv80

    ecv80

    Joined:
    Oct 1, 2017
    Posts:
    28
    Hi!, Thanks for the quick reply

    Rotation is 0, -180, 0 as per the editor. But I thought that wouldn't affect transform direction vector like transform.right in any way? Specially not in this strange way.

    Here's another test I run. I didn't clean it up this time, to post quick:

    Code (CSharp):
    1.  
    2. transform.rotation
    3. {(0.0, 1.0, 0.0, 0.0)}
    4. eulerAngles: (0.0, 180.0, 0.0)
    5. normalized: (0.0, 1.0, 0.0, 0.0)
    6. w: 0
    7. x: 0
    8. y: 1
    9. z: 0
    10. Static members:
    11. transform.position
    12. {(62.6, 0.5, 440.2)}
    13. magnitude: 444,6725
    14. normalized: (0.1, 0.0, 1.0)
    15. sqrMagnitude: 197733,6
    16. x: 62,59476
    17. y: 0,5000001
    18. z: 440,2445
    19. Static members:
    20. Thread finished: <Thread Pool> #3
    21. transform.right
    22. {(-1.0, 0.0, 0.0)}
    23. magnitude: 1
    24. normalized: (-1.0, 0.0, 0.0)
    25. sqrMagnitude: 1,000001
    26. x: -1
    27. y: 0
    28. z: 0
    29. Static members:
    30. Thread finished: <Thread Pool> #7
    31. transform.right*dT*speed
    32. {(-3.3, 0.0, 0.0)}
    33. magnitude: 3,271693
    34. normalized: (-1.0, 0.0, 0.0)
    35. sqrMagnitude: 10,70397
    36. x: -3,271693
    37. y: 0
    38. z: 0
    39. Static members:
    40. transform.position+=transform.right*dT*speed
    41. {(59.3, 0.5, 440.2)}
    42. magnitude: 444,2237
    43. normalized: (0.1, 0.0, 1.0)
    44. sqrMagnitude: 197334,7
    45. x: 59,32307
    46. y: 0,5000001
    47. z: 440,2445
    48. Static members:
    49. transform.position+=transform.right*dT*speed
    50. {(56.1, 0.5, 440.2)}
    51. magnitude: 443,7988
    52. normalized: (0.1, 0.0, 1.0)
    53. sqrMagnitude: 196957,3
    54. x: 56,05137
    55. y: 0,5000001
    56. z: 440,2446
    57. Static members:
    58. transform.position+=transform.right*dT*speed
    59. {(52.8, 0.5, 440.2)}
    60. magnitude: 443,3976
    61. normalized: (0.1, 0.0, 1.0)
    62. sqrMagnitude: 196601,4
    63. x: 52,77968
    64. y: 0,5000001
    65. z: 440,2448
    66. Static members:
    67. transform.rotation
    68. {(0.0, 1.0, 0.0, 0.0)}
    69. eulerAngles: (0.0, 180.0, 0.0)
    70. normalized: (0.0, 1.0, 0.0, 0.0)
    71. w: 0
    72. x: 0
    73. y: 1
    74. z: 0
    75. Static members:
    76.  
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,741
    The transform's rotation absolutely affects transform.right (why would transform.right exist if it didn't?). If your rotation is 0,-180,0 though it shouldn't cause the Z to move. I'm wondering if there's a precision issue with that though.

    As an aside, I have no idea what the code is supposed to be that you're posting. I assume some sort of custom console or something. Can you post the actual C# code that causes the issue?
     
  5. ecv80

    ecv80

    Joined:
    Oct 1, 2017
    Posts:
    28
    I'm just throwing those lines at the debugger in VSCode and that's what's outputting.

    The relevant code is really just what I posted at first:

    transform.position += transform.right * dT * speed;


    This is the whole code. And disabling the script in the editor does stop the mysterious z increment (and x, of course):

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Vehicle : MonoBehaviour {
    6.  
    7.     bool initialized=false;
    8.  
    9.     //Displacement
    10.     public float speed=20f;
    11.  
    12.     //Stretching
    13.     // float stretchingSpeed=2f;
    14.     // bool stretchingRight=true;
    15.     // public float stretchHighLimitX;
    16.     // float stretchLowLimitX;
    17.  
    18.  
    19.     Transform[] vehicleBodies;
    20.     public float vehicleLength;
    21.  
    22.     //Sound
    23.     public AudioSource musicOrHorns;
    24.     public bool music=true;
    25.     public float delayBeforePlay=0f;
    26.     public float timeSinceLastPlay=0f;
    27.  
    28.  
    29.     public void Init(float speed) {
    30.         initialized = true;
    31.         this.speed = speed;
    32.         gameObject.SetActive(true);
    33.  
    34.         // stretchHighLimitX = transform.localScale.x * 1.05f;
    35.         // stretchLowLimitX = transform.localScale.x * 0.95f;
    36.  
    37.         vehicleBodies=new Transform[transform.childCount];
    38.         for (int i=0; i<transform.childCount; i++)
    39.             vehicleBodies[i]=transform.GetChild(i);
    40.  
    41.         //Get vehicle bounds
    42.         Bounds vehicleBounds = new Bounds ();
    43.         MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter> ();
    44.         foreach(MeshFilter meshFilter in meshFilters) {
    45.             vehicleBounds.Encapsulate(meshFilter.sharedMesh.bounds);
    46.         }
    47.         vehicleLength = Mathf.Max (vehicleBounds.size.x, vehicleBounds.size.y, vehicleBounds.size.z);
    48.  
    49.         // stretchingSpeed = speed / vehicleLength / 2f;
    50.  
    51.         foreach (Transform body in vehicleBodies)
    52.             body.localPosition = new Vector3 (vehicleLength/2f, 0f, 0f);
    53.  
    54.         //Sound
    55.         // foreach (AudioSource aud in gameObject.GetComponentsInChildren<AudioSource>())
    56.         //     if (aud.clip==null)
    57.         //         musicOrHorns=aud;  
    58.         musicOrHorns=gameObject.GetComponentsInChildren<AudioSource>()[1];
    59.         if (musicOrHorns==null)
    60.             return;
    61.  
    62.         music=Random.value<.025f?true:false;
    63.  
    64.         if (music) {
    65.             musicOrHorns.clip=Resources.Load<AudioClip>("Sounds/liana");
    66.             musicOrHorns.pitch=1f;
    67.             musicOrHorns.loop=true;
    68.             musicOrHorns.Play();
    69.         }
    70.         else
    71.         {
    72.             //If this is a truck set the correct horn, else set cars horns
    73.             if (gameObject.name.StartsWith("Trailer"))
    74.                 musicOrHorns.clip=Resources.Load<AudioClip>("Sounds/truckhorn");
    75.             else
    76.                 //Weird horns (1-3) are less likely to occur
    77.                 musicOrHorns.clip=Resources.Load<AudioClip>("Sounds/horn"+(Random.value<.025f?Random.Range(1,4):Random.Range(4,16)));
    78.  
    79.             musicOrHorns.loop=false;
    80.             musicOrHorns.pitch=Random.Range(.9f, 1.1f);
    81.             delayBeforePlay=Random.Range(0f, 30f);
    82.         }
    83.     }
    84.  
    85.     // Use this for initialization
    86.     protected void Start () {
    87.         if (!initialized)
    88.             Init (speed);
    89.     }
    90.  
    91.     // Update is called once per frame
    92.     protected void Update () {
    93.         float dT = Time.deltaTime;
    94.  
    95.         if (GameManager.gameState==GameStates.paused)
    96.             return;
    97.  
    98.         //Position
    99.         transform.position += transform.right * dT * speed;
    100.  
    101.         if (transform.position.x * transform.right.x >= 250f)
    102.             transform.position -= transform.right * 500f;
    103.  
    104.         // transform.position = new Vector3(transform.position.x+dT*speed, transform.y, transform.position.z);
    105.  
    106.         // if (transform.position.x * transform.right.x >= 250f)
    107.         //     transform.position -= transform.right * 500f;
    108.  
    109.  
    110.         // // Scale
    111.         // if (stretchingRight) {
    112.         //     transform.localScale = new Vector3 (transform.localScale.x + dT * stretchingSpeed, transform.localScale.y - dT * stretchingSpeed, transform.localScale.z);
    113.  
    114.         //     if (transform.localScale.x >= stretchHighLimitX) {
    115.         //         stretchingRight = false;
    116.         //         transform.position+=transform.right*vehicleLength*transform.localScale.x;
    117.         //         foreach (Transform body in vehicleBodies)
    118.         //             body.localPosition = new Vector3 (-vehicleLength/2f, body.localPosition.y, body.localPosition.z);
    119.         //     }
    120.         // }
    121.         // else {
    122.         //     transform.localScale = new Vector3 (transform.localScale.x - dT * stretchingSpeed, transform.localScale.y + dT * stretchingSpeed, transform.localScale.z );
    123.  
    124.         //     if (transform.localScale.x <= stretchLowLimitX) {
    125.         //         stretchingRight = true;
    126.         //         transform.position-=transform.right*vehicleLength*transform.localScale.x;
    127.         //         foreach (Transform body in vehicleBodies)
    128.         //             body.localPosition = new Vector3 (vehicleLength/2f, body.localPosition.y, body.localPosition.z);
    129.         //     }
    130.         // }
    131.  
    132.  
    133.         //Sound
    134.         if (musicOrHorns && !music && !musicOrHorns.isPlaying) {
    135.             timeSinceLastPlay+=dT;
    136.  
    137.             if (timeSinceLastPlay>=delayBeforePlay) {
    138.                 timeSinceLastPlay=0;
    139.                 delayBeforePlay=Random.Range(musicOrHorns.clip.length*120f, musicOrHorns.clip.length*240f);
    140.                 musicOrHorns.Play();
    141.             }
    142.         }
    143.     }
    144.  
    145.     //My methods
    146. }
    147.  
    As for the rotation affecting the direction vectors, I think I understand what you mean. So maybe there are rotation and position precision errors that are building up after a while, since 0f is probably not really just 0?
     
  6. ecv80

    ecv80

    Joined:
    Oct 1, 2017
    Posts:
    28
    @StarManta So I'm using this for the meantime:

    transform.position = new Vector3(transform.position.x+transform.right.x*dT*speed, transform.position.y, transform.position.z);

    Now I see why I was using transform.right :D Doing the above
    transform.position=new Vector3(transform.position.x+dT*speed, transform.position.y, transform.position.z)
    makes some of my cars run backwards :p

    Now I wonder if this way of moving them is as efficient as the former one, with that "new" in there? But maybe the former does exactly the same with the overloaded operators anyways? But it feels a little slower now.
     
  7. brigas

    brigas

    Joined:
    Oct 4, 2014
    Posts:
    522
    do you have the same problem if you use


    transform.position += Vector3.Left * dT * speed;
     
  8. ecv80

    ecv80

    Joined:
    Oct 1, 2017
    Posts:
    28
    No, I don't. And the same is true for Vector3.right.
    This makes me think I must have some very small offset in my prefabs rotation. Editor shows 0,0,0 for their rotation tho. I'm thinking perhaps this isn't exactly a problem with my script (other than I shouldn't have been doing that for my use case) nor a bug in Unity but the problem is somewhere in the modeler (Blender), export and import pipeline, especially considering up is z in Blender.
    Thanks!
     
  9. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,713
    I have seen slight drifts from using a Transform's rotation even at what you would intuit would not, such as 90, 180 and 270 degree rotations.

    Also when you import from Blender3D, the import step converts from Blender's right-handed coordinate system to Unity's left-handed coordinate system. That's why all Blender objects import default rotated as (-90,0,0), but if you look in the inspector, sometimes it reads as (-89.999999,0,0) for instance.
     
    ecv80 likes this.