Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question How can I precisely time movement during runtime?

Discussion in 'Scripting' started by BoxTurtle_Games, May 27, 2024.

  1. BoxTurtle_Games

    BoxTurtle_Games

    Joined:
    May 6, 2022
    Posts:
    47
    I am working on a project for a calculus course, and want to relate vector-valued functions to calculating where a thrown object will land (excluding things like wind resistance). I wrote a function to calculate the position at an instant of an object that is launched with a force 200 units upward and 200 units to the right relative to the origin. The issue I have been having though, is that the object doesn't stop at the precise instant I want it to. I have this coroutine below to apply a force, then stop the particle at the time represented by takeposat.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class b : MonoBehaviour
    6. {
    7.     [Range(0f, 2000f)]
    8.     public float sideforce;
    9.     [Range(0f, 2000f)]
    10.     public float upforce;
    11.     public Rigidbody rb;
    12.     public float takeposat;
    13.     void Start()
    14.     {
    15.         StartCoroutine("stop");
    16.     }
    17.     public IEnumerator stop()
    18.     {
    19.  
    20.         rb = GetComponent<Rigidbody>();
    21.         rb.useGravity = true;
    22.         rb.AddForce(sideforce, upforce, 0f);
    23.         yield return new WaitForSeconds(takeposat);
    24.         rb.useGravity = false;
    25.         rb.velocity = Vector3.zero;
    26.     }
    27. }
    The only issue is that the particle consistently exceeds the predicted value by a little bit. The predicted value at 2 seconds is an x-position of 8, and a y-position of -11.6. The actual values are an x-position of 8.079995 and a y-position of -12.11193. This seems like a timing error, and I would like to know if I can check position at a more precise time than what I have set up for more accurate results. I tried increasing the framerate to 120FPS, but it didn't really do much.

    UPDATE: this may be more than a timing issue, as the x-coordinate when I detect collision at time = 2 seconds is only off by 0.0001, while the y-coordinate is off by 0.4.

    I don't know if this still applies to unity if i ask this but is the function below correct for calculating the position of an object with a mass of 1? Screen Shot 2024-05-26 at 9.27.32 PM.png
     
    Last edited: May 27, 2024
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,212
    A couple of things you should be aware of:

    1) Unity does its physics simulation at a specific timing interval. By default, it performs 50 physics updates per second, regardless of your game's framerate. (It seems you might be aware of this due to the "/ 50" in your equation...) But this means that when working with rigidbodies, you should be doing so within either the FixedUpdate() method, or your coroutine should use "yield return new WaitForFixedUpdate()" to wait in step with the physics updates. But this also means that running your game at 150 FPS won't change the physics outcome.

    2) Positions in Unity only have so much precision. I wouldn't expect to get any more accurate than position values of about 0.0001. Unity's built-in physics isn't really accurate for precise simulations. (Though showing projectile trajectory, you should probably get close.) I'm not really sure you should expect as much precision as you're hoping for in those x/y values.

    3) The further your positions get from the global position (0,0,0), the worse the precision gets. This is an issue with large worlds, where maybe you're thousands of meters from (0,0,0). In those cases, the accuracy of the position values really starts to degrade.

    I don't recall whether your equation is reasonable or not (it's been a while since I implemented a trajectory predictor).
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    39,369
    CodeRonnie likes this.
  4. BoxTurtle_Games

    BoxTurtle_Games

    Joined:
    May 6, 2022
    Posts:
    47
    I don't even think its a timing thing anymore, because even when I stop the object at the precise x-position that I want, the y-position is still off by 0.2. It also isnt that far from the origin (4 units along x-axis, around 1 unit on y-axis), so that rules out floating point innacuracy.

    I also don't have reason to suspect the equation is at fault, because I had 2 people verify it, one of which being a calculus teacher.
     
  5. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,687
    How close you are to origin isn't the only source of inaccuracies. Simply performing calculations on floating point numbers will do it too. Check the value at every step of the calculation and see what it's coming up with.

    https://stackoverflow.com/questions/2100490/floating-point-inaccuracy-examples/2100502#2100502

     
    Last edited: May 28, 2024
  6. BoxTurtle_Games

    BoxTurtle_Games

    Joined:
    May 6, 2022
    Posts:
    47
    Are you saying that physics simulations become less accurate as they run due to an increasingly large number of calculations performed on not exact numbers, and that could be the source of my error? If so, is there even a way to fix that?
     
  7. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,687
    Yes, it's very likely that's what's happening, and the only fast way to mitigate it is to either truncate or round. You should still test the values at every step of the calculation to see if it's actually what's happening.
     
  8. BoxTurtle_Games

    BoxTurtle_Games

    Joined:
    May 6, 2022
    Posts:
    47
    I did a little more testing, and I think that you're right about the inaccuracy in the physics calculations. I could probably use the equation I found to be correct to adjust the position every frame, but that kind of makes the point of my project moot. With that said, how exactly do i truncate/round values for physics calculations if i'm not really manipulating physics calculations in my script? Also, is it possible some physics setting could be toggled on/off or modified to make the simulation more accurate? Or reducing the amount of physics calculations run per frame to reduce innacuracies?
     
  9. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,687
    Oh, I thought you were doing the math yourself. I don't know in that case. :p
     
  10. BoxTurtle_Games

    BoxTurtle_Games

    Joined:
    May 6, 2022
    Posts:
    47
    Sorry to keep the thread going this long, but I figured something out. The inaccuracy is linear. For every second the simulation runs, somehow the actual y-position is off by -0.1, no matter what the force applied is. This means that the actual y-position can be modeled by:

    ((-9.8/2) * Time^2 + (upforce/50) * Time) - (0.1x)

    I have no idea why this is, and I am worried about messing with the physics because then it might not be reflective of an actual physics simulation. If anyone can present any reason for why this might be happening, then that would be much appreciated so I can justify messing with physics in my project.