Cannot figure out why my BPM is slightly off

Timing my script with a stop watch, I see it is slightly out of sync. And can’t figure why. Is there anything I should be doing to keep it correct? I’ve attached the whole (unfinished) script in here, to put it all on context.

public class YPop : MonoBehaviour {
	public float startTime = 1.0f;
	public float moveAmount = 0.25f;
	public float startHeight = -0.5f;
	// public Collider Trigger;
	public float beatTime = 60.0f;
	float timer;

	float rnd;
	float oTime;
	bool UpDown = false; //up true, down false

	void Start(){
		transform.position = new Vector3(transform.position.x, startHeight + transform.parent.position.y, transform.position.z);

	}
	void Update () {
		if(timer >= 0.0f)
			timer -= Time.deltaTime;

		else{
			StartCoroutine(WaitToPop(startTime));
			timer = (60f / beatTime)*0.5f;
		}

		if(transform.position.y > startHeight + transform.parent.position.y)
			transform.Translate(Vector3.down * Time.deltaTime);

	}

	IEnumerator WaitToPop(float startTime){
		rnd = Random.Range(0.0f, moveAmount);
		yield return new WaitForSeconds(startTime);
		if(UpDown){
			transform.Translate(Vector3.up * rnd);
			UpDown = false;
		}
		else{
			UpDown = true;
		}
	}

	void OnCollisionStay(Collision col){

	}
}

Well the first thing that springs to my mind is that your script doesn’t consider how far below 0 your timer variable is when it then resets it. It’s highly unlikely that subtracting delta time will nicely land you on 0 each time, you’re likely to be tiny amounts below 0 each time. Every time you then reset your timer as if it was from exactly 0, you begin to accumulate tiny sync errors with each loop of the timer.

Granted I’m not sure if this sort of error accumulation is enough to be significantly out of sync unless you’re experiencing lag spikes or poor frame rate, but its something to consider. Getting around it is as simple as changing your = into a += when resetting your timer. That way the overlap below 0 is taken into account as your next loop of the timer starts with that offset.

timer = (60f / beatTime)*0.5f; // Old
timer += (60f / beatTime)*0.5f; // New

Like i said, might be only a minor contribution to your sync error. but worth noting, and maybe it will have a bigger effect that I’m imagining.