I am attempting to make a consistent firing rate.
I have done a lot of research on figuring out consistent rates that are independent of framerate and most of the articles about it use deltaTime. However, most timers do not. I have a timer that works as long as the interval is not less that “0.2”. Any number less than that has inconsistent results depending on the framerate. Specifically, when I play the project in the maximized window, versus a small window.
Here is the code I am using. I know this has been beaten to death, so forgive me, please. I assume I must use some form of deltaTime multiplier somewhere.
using UnityEngine;
using System.Collections;
public class Shooter : MonoBehaviour {
// public GameObject bullet;
// public Transform cam;
public float interval;
public float lastFire = -9999;
public int shotsFired;
void Update ()
{
if(Time.time < 5)
{
if(CanFire ())
{
lastFire = Time.time;
// Instantiate(bullet, cam.position, cam.rotation);
shotsFired ++;
}
}
}
bool CanFire()
{
return Time.time >= lastFire + interval;
}
}
I have toggled out the bullet references so that it can be easily tested. The reason I know it is inconsistent is because I implemented a test that lasts for a specific amount of time. I realize my test may be faulty and could be the actual problem. If so, please let me know.
I really appreciate any and all help.
Thanks, and God bless!
Howey
eyee
2
Hello!
It would be much easier to use a coroutine. Set CanShoot to false when the Player is shooting and start a Coroutine with the amount of time.
using UnityEngine;
using System.Collections;
public class example : MonoBehaviour {
void Shoot(){
if(CanShoot){
CanShoot = false;
print("Shooting");
StartCoroutine(Wait(0.1F));
}
}
IEnumerator Wait(float waitTime) {
yield return new WaitForSeconds(waitTime);
CanShoot = true;
}
}
I hope this helps!
“if(Time.time < 5)” is used to create a consistent test of firing rate between varying framerates.
Here are the results of the tests of all of the recommendations you guys gave me: This tests the number of shots fired in a 5 second period with slower and faster framerates and a 0.01 time interval between shots:
Coroutine: Slow = 93 shots, Fast = 147 shots
Invoke: Slow = 130, Fast = 193
Original: Slow = 135, Fast = 293
FixedUpdate Original: Slow = 250, Fast = 250
// This is the Original test
void OriginalTest()
{
if(CanFire ())
{
lastFire = Time.time;
shotsFired ++;
}
}
bool CanFire()
{
return Time.time >= lastFire + interval;
}
// This is the Invoke test
void InvokeTest()
{
if(canFire)
{
canFire = false;
shotsFired ++;
Invoke ("invoke", interval);
}
}
void invoke()
{
canFire = true;
}
// This is the Coroutine test
void CoroutineTest()
{
if(canFire)
{
canFire = false;
shotsFired ++;
StartCoroutine(Wait(interval));
}
}
IEnumerator Wait(float waitTime)
{
yield return new WaitForSeconds(waitTime);
canFire = true;
}
}
Results:
The FixedUpdate method appears to be the only one that works independent of the framerate. However, that creates another issue, which is that FixedUpdate tends to completely miss Input sometimes.
Is there a solution for that problem?
I do want it to fire exactly when the player presses the fire button.
Thanks again, I really appreciate all of your responses.