How do you measure milliseconds at runtime?

Hi everyone,

I am making a racing game and using Trackmania as an example, I would like to register the time it takes the player to finish the race.

At the moment I am using the FixedUpdate which only happens every 0.02 seconds which is far from the 0.001 seconds I would like to achieve.

Is there a way to achieve this and how is it possible?

…Did you forget about Time.deltaTime?

Ahh, no I didn’t of course but what I am doing is using a collider to detect the collision between my car and my checkpoint. Since it is managed by the Physics so FixedUpdate, it only happens 50 times per seconds or every 0.02s.

Maybe there is another way to achieve that, I don’t know. But I am very far from the 0.001s I would like to achieve and I don’t know if Time.deltaTime could help me.

FixedUpdate is for controlling rigidbodies, not for recording time.

You literally just need a float value that you increment with Time.deltaTime in Update every frame, and turn off the timer when the collision happens. You’re thinking about this completely wrong.

But even at 144 frames per second, the most accurate time I could get was 1/144=0.00694, which is still higher than 0.001s.

I won’t be able to get what happens between two frames.

Also, from the Unity Scripting API of Collider.OnTriggerEnter: " The events are invoked during simulation, which happens after all FixedUpdate methods are called, or within the scope of Physics.Simulate, if you’re using manual physics simulation."

1 Like

Then use this: Stopwatch Class (System.Diagnostics) | Microsoft Learn

Still doesn’t mean you need to record your time in FixedUpdate. I don’t understand why you think this.

Also, in case you don’t know, FixedUpdate doesn’t happen exactly every 0.02 seconds, it runs before Update() if said interval has been passed, and may run multiple times if more multiples of 0.02 seconds have passed between frames (such as during a big lag spike). Basically it plays catch-up. It is not a reliable form of timer.

Instead of incrementing a timer you can wait for the end of the race and then subtract the race start time from Time.timeAsDouble to get the amount of time passed since the start of the race.

1 Like

But I won’t have the accuracy I am looking for. What I mean by that is the fact that OnTriggerCollider doesn’t happen every 0.001s but less often like around 0.02s.

So between two update, yes I have passed the checkpoint but when exactly, I don’t know.

In both case, the next frame, my car will pass the checkpoint but since the velocity is not the same, it should take less time to the second case than the first one.

It would work fine for code but not when depending on Update of FixedUpdate which constrain the refresh rate.

… Like I literally just explained, FixedUpdate gets called before Update. Thinking on it, it’s timing accuracy is probably the same as Update anyway. You’re worrying about nothing.

Yes I agree about the time it will give me but since I will ask this time during Update of FixedUpdate, I will loose this accuracy.

Sorry but I not quite sure what does it mean. When I do a debug.log in update and in FixedUpdate, The rate is not the same. One is called every 0.02s (FixedUpdate) and the other evry frame.

Well you logic is tied to Unity’s so you can’t run anything more accurately than Unity already is.

Besides Time.deltaTime is going to give you a value more than 3 decimal points so to the player it will look accurate enough.

Now that you are no longer angry, do you have any idea how I can decouple it from Unity?

I was thinking about using Rigidbody.SweepTest to know the distance bewteen my collider car and my checkpint before the collision and using speed = distance / time, I could find the time it takes to reach the checkpoint.

I mean you literally can’t measure this any more accurately than Unity is. You cannot tell any more accurately than Unity when the car has past the checkpoint.

As you’ve said, update loops won’t give you the necessary precision.

But, as I understand what you want to achieve, you’re not trying to handle input at higher precision but just want to accurately calculate the time a player reached the finished line?

In this case, you should take an analytical approach. It doesn’t matter how accurate the update loop is, as you don’t actually need to have an update right as the car reaches the line, you just need to calculate it accurately enough after the player has crossed the finish line.

In the image you posted, you can know the car’s position in last and current frame as well as how long the frame took (its fixed delta time). Using this, you can calculate the exact time it took for the car to touch the finish line during the last physics frame.

If the geometry is a bit too complicated for a direct geometric calculation, you might also be able to use one of the many sweep tests Unity provides (look on Rigidbody, Collider and Physics). This will calculate the distance a rigidbody/collider/ray will need to travel to hit another collider, which is independent of the frame rate and which you could run in the frame after the car has reached the finish line.

2 Likes

But none of the current engines can do tests every millisecond, but Trackmania fakes that in some way, so I am pretty sure there is a way in Unity too.

Maybe this will help:
• How to find time in milliseconds? - Questions & Answers - Unity Discussions

What a great answer!

I was thinking about that too, which is why I mentioned the Sweeptest, because I have just discovered this method.

I am trying to use it but it is a bit weird how it works as it seems to calculate from the centre of the collider and not for each point.

1 Like

It really depends on your use case and how complicated & accurate you want to make it.

You could just assume every car is approximated by a sphere and then the geometric calculation of when the sphere touches the plane of the finish line is not too complicated. Depending on how your cars look and how orderly they pass the finish line, this might work accurately enough.

To make things more accurate, you could use a box instead of a sphere. The geometric calculation then gets more complicated but it’s still manageable (testing the box’s six planes against the finish plane and picking the one with the shortest distance).

If you want to take the actual collision shape of your cars into account, you need to use on the physics queries and they can be a bit awkward to use. Most of them are designed to predict collisions, not to figure out the exact collision after the fact, which would be the most natural in your case. You could try to sweep ahead to find the finish line before the car touches it, maybe limiting it to only cars close enough to the finish line. Otherwise, you can try the Physcis.*Cast methods or Physics.ComputePenetration, which allow defining the start position freely but are much more cumbersome to use.

2 Likes