otset
otset

Reputation: 21

Inconsistent race times on a completely straight track

I'm making a 2D topdown racing game which measures the time it takes the player to finish a track and I noticed that even on a completely straight track, the finish times are not always the same (the car accelerates automatically).

I've tried setting both the Maximum allowed timestep and Fixed Timestep to the same value (both are 0.02), not sure if that has any impact on this.

For the timer I use System.Diagnostics.Stopwatch which starts in the Start() method

void Start()
    {
        checkpoints = GetComponentsInChildren<Checkpoint>();
        sw.Start(); //stopwatch starts
        Load();
        checkpointsReached = 1;
        nextCheckpoint = checkpoints[checkpointsReached];
    }

and stops when the car touches a trigger marked as finish.

internal void CheckpointReached(Checkpoint checkpoint)
    {
        if (nextCheckpoint != checkpoint)
            return;

        checkpointsReached++;

        if (checkpoint.isFinish)
        {
            sw.Stop();  //stopwatch stops after reaching Finish
            EndRace();
            return;
        }

        if (checkpointsReached == checkpoints.Length)
        {
            checkpointsReached = 0;
        }

        nextCheckpoint = checkpoints[checkpointsReached];
    }

To get the race time I use sw.Elapsed.ToString("ss','ffff");

The car acceleration is done in another script

void FixedUpdate()
    {
        Rigidbody2D rb = GetComponent<Rigidbody2D>();
        rb.AddForce(transform.up * speedForce);  //acceleration


        //turning and stuff
        rb.angularVelocity = Input.GetAxis("Horizontal") * torqueForce;
        rb.velocity = ForwardVelocity() + RightVelocity() * driftFactor;

I want the game to be consistent and fair so I expect the finish time on a straight road to be always the same, but right now the times are in range of +/- 0.02s from each other.

Upvotes: 2

Views: 102

Answers (2)

shingo
shingo

Reputation: 27199

Use Time.time if you want consistent duration, it's always a multiple of Time.fixedDeltaTime in FixedUpdate event. If you want more precision, decrease that value.

Upvotes: 0

zambari
zambari

Reputation: 5035

Stopwatch is a very precise time measurement device, and 0.02s equals one frame if you are pushing 50 FPS. Unity's time system is discrete, and increments only when the new frame (or physics frame) starts, so nothing 'moves in the background', you cannot expect accuracy higher than frame - there is no sub-frame times in Unity.

Please note that if you measure using stopwatch, you are measuring hard realtime, which means that if your game freezes for a split second, it will add to the stopwatch time, but will not add to the game time. Generally you should be using UnityEngine.Time.time to measure game time, stopwatch is generally used for performance diganostics (thats why its under System.Diagnostics namespace), not for business logic.

Also, humans cannot 'see' a 0.02s difference under normal conditions.

Upvotes: 3

Related Questions