-
-
Save kurtdekker/0da9a9721c15bd3af1d2ced0a367e24e to your computer and use it in GitHub Desktop.
using UnityEngine; | |
using System.Collections; | |
public class CallAfterDelay : MonoBehaviour | |
{ | |
float delay; | |
System.Action action; | |
// Will never call this frame, always the next frame at the earliest | |
public static CallAfterDelay Create( float delay, System.Action action) | |
{ | |
CallAfterDelay cad = new GameObject("CallAfterDelay").AddComponent<CallAfterDelay>(); | |
cad.delay = delay; | |
cad.action = action; | |
return cad; | |
} | |
float age; | |
void Update() | |
{ | |
if (age > delay) | |
{ | |
action(); | |
Destroy ( gameObject); | |
} | |
} | |
void LateUpdate() | |
{ | |
age += Time.deltaTime; | |
} | |
} |
@kurtdekker I'm curious why you changed from coroutine to the current method?
@omundy @kurtdekker I'm also wondering the same thing. You can have the same behaviour with Coroutines. Callbacks from Update + LateUpdate might be slower too compared to the pure boolean comparison of Coroutine in Update (I suppose it's running in Update, although I'm not sure).
why not coroutine ?
I have seen this person comment on coroutine functionality and use cases on several different threads, and this is one of many examples of alternatives to coroutines that they have made available. They preach caution around using coroutines and I have gone back and forth on their philosophy for years now. I'm sure I can't put it as eloquently (or informatively) as they can, but my understanding is that coroutines, while convenient, can quickly become unmanageable if relied on too heavily and they can introduce bugs if used in situations more complex than the simplest "set it and forget it" scenarios.
If your project is something extremely small or is a prototype, then I'd go with coroutines to get it working, but if you want scalability and precise execution control, you should probably take the time to implement something like this in most cases.
A whole coroutine brain dump of theirs that I just came from:
https://discussions.unity.com/t/coroutine-for-heavy-operation/886052/2
If you want a CallAfterDelay instance to die at the same time as the rest of your scene, so you don't get null references if you change scenes while one of these is pending, I find the easiest way is to parent the CallAfterDelay instance to the script where you call it from, something like this:
CallAfterDelay.Create( 2.0f, () => {
myButton.interactive = true;
}).transform.SetParent( myButton.transform);
That will set myButton to interactive in 2 seconds, but if you change scenes (or destroy myButton) before then, it avoids firing a pesky missing / destroyed reference.