How to call a function every Y amount of seconds, but Y changes depending on other events?

Viewed 201
InvokeRepeating("MoveEnemies", 1.0f, ratioAlive);

I called this in the start method. However, it will only run with the original ratioAlive value.

If I run it in the update, it runs every frame which I do not want.

1 Answers

If you literally need to call a function every N seconds (where N != const) and you cannot implement it via events, then you can try using a Coroutine.
It will call Foo() every N seconds automatically, but N may be changed in this class or another one:

public float Delay; // Your "N"

private IEnumerator InvokeRepeatedly () { // Coroutine that invokes the function
    while (true) {
        Foo(); // Call
        yield return new WaitForSeconds(Delay);// Wait
    }
}

private void Foo () {...} // The function

You can also send some arguments:

private IEnumerator InvokeRepeatedly (int a, bool b) {
    while (true) {
        Foo(a, b);
        yield return new WaitForSeconds(Delay);
    }
}

private void Foo (int a, bool b) {...}

Moreover, you can define your own delegate (or use the existing) and call different functions via the Coroutine, unless their parameters or return value differ.

delegate void SomeDelegate(float a, bool b); // Defininf delegate type

private IEnumerator InvokeRepeatedly (SomeDelegate func, float a, bool b) {
    func(a, b); // Call function sent as an argument
}

private void Func1 (float num, bool isTrue) {...} // First fucntion
private void Func2 (float num, bool isTrue) {...} // Second function
// Whatever void function that takes these arguments would be appropriate.

If so, you can call it this way:

SomeDelegate func = new SomeDelegate(Func1); // Define a delegate instance
StartCoroutine(InvokeRepeatedly(func, 1.0f, true)); // Call coroutine that will call function
Related