Time.time vs Time.deltatime vs Real Time

Hi,

another issue i have here. its more of a “prefectionist” nature of mine i guess but yet i wonder.

I know the definitions of the times:
time is since game started
deltatime is how long the last frame took.

So i have a gun and it has a cooldown.
But the shoots dont die exactly at the same distance.
They somhow vary in their range quite much.

I tried both ways:
Adding up deltatime to a variable and if that >= X, then i can shoot again.
or
Storing Time.time+cooldown and waiting for Time.time to catch up.

The later gave me better results but still, there is a vary in it.
(I could let the bullets fly out of the screen where this doesnt matter, but i would like to not use dirty tricks and make it clean)

greets

my used code atm (a weapon that should shoot bullets every 0.5 sec, those should stay alive for 1 sec):

using UnityEngine;
using System.Collections;

public class TimedLifeObject : MonoBehaviour {
	
	private float lifetime_Limit;
	private float lifetime_Timer;
	
	// Use this for initialization
	protected virtual void Start () {
		lifetime_Limit = 1;
		lifetime_Timer = Time.time + lifetime_Limit;
	}
	
	// Update is called once per frame
	protected virtual void Update () {
		if (Time.time >= lifetime_Timer)
			Destroy(gameObject);
		
		
	}
	
	public float lifetime_Max {
		get { return lifetime_Limit;}
	    set { lifetime_Limit = value; }
	}
	
 	public float lifetime_Left {
		get { return lifetime_Timer; }
	}	
}

and:

using UnityEngine;
using System.Collections;

public class PlayerGunShoot : MonoBehaviour {
    private float cooldown_Timer;
	private float cooldown_Limit;
	private GameObject bullet;
	
	void Start() {
		cooldown_Limit = .1F;
		cooldown_Timer = cooldown_Limit + Time.time;
		transform.Rotate(new Vector3(0,0,90));
	}

	void Update () {
		
		
		#region shoot gun
		
		if( Input.GetAxis("Fire1") == 1  Time.time >=  cooldown_Timer){
			cooldown_Timer = cooldown_Limit + Time.time;
			bullet = (GameObject) Instantiate(Resources.Load("Prefabs/Bullet"), transform.position, transform.rotation);
			print ("from start: "+Time.time );
			//print ( cooldown_Limit);
			print ("cooldtimer: "+cooldown_Timer );
		}
		#endregion
		
    	
		
	}
}

every frame takes a different amount of time to change. Which means they won’t necessarily directly overlap with the cooldown time.

Say you shoot on frame N, and you have a cool down of 1 second.
Say your game is running at an average of 60 fps, this means 0.0166666… seconds pass between every frame on average. One would suspect that after 60 frames the cool down will be over. BUT 2 issues creep in:

  1. 1/60th of a second is a repeating number, float error will creep in, and over 60 frames we can easily loose 1 or 2 frames to error.
  2. frames aren’t fixed (though you can access FixedUpdate for a fixed change in time between frames), so even more overlap could occur. How many times do you add 3 to get 10? 3 times is to little, 4 times is to much, you’re going to be 2 over your target.

Thing is games don’t have to be perfect… does it matter if the bullet lasts for this micro second of time that the player isn’t going to even notice?

3 Likes

lordofduct,

i kinda thought so for myself.
Thing is im new to unity and i just wanted to
go sure that i dont overlooked some kind of
technike that i could use in here.

The player will not notice this at all.

And another big Thanks to you!

Just adding my $0.02. Have you tried Coroutines?
I am not sure how perfectly timed they are. But heres how it could work.

public class TimedLifeObject : MonoBehaviour
{

    void Start()
    {
        StartCoroutine(KillMeAfter(1));
    }

    IEnumerator KillMeAfter(float secondsToWait)
    {
        yield return new WaitForSeconds(secondsToWait);
        Destroy(gameObject);
    }
}

in that case you could also use Invoke…

public class TimedLifeObject : MonoBehaviour
{

    void Start()
    {
        Invoke("KillMe", 1.0f);
    }

    void KillMe()
    {
        Destroy(gameObject);
    }

}

CoRoutine was still slightly off. But Invoke happened to be really, really close. If I passed in whole numbers, or 10ths of numbers they were spot on.

But you still shouldn’t expect it to be perfect.

Thans for the info about their accuracy.

My intuition which might be totally wrong is this:

Floating point numbers lose precision very rapidly as they increase. My impression is that something on the order of 1/2 of all possible values a float can store lie in the range -1 to 1. Therefore it’s better to work with smaller numbers wherever possible to reduce floating point precision error. As the game goes on, it’s my understanding that Time.time becomes less and less reliable as it grows.

Therefore I would prefer the adding Time.deltaTime each frame to a variable until it reaches my desired duration.

Edit: wow can’t believe I got sucked into replying to this necro…