- Home /
Why can MonoBehavior.Start() return an IEnumerator?
The expected method signature is typically void Start()
but in the Unity 4.5 project I'm working on, I've seen several instances of where another developer did this:
IEnumerator Start() {
do {
yield return null;
} while (SomeCondition());
... startup code ...
}
This appears to be perfectly legal but I can't find any reference to it in the Unity manual. This code compiles and during execution, the implied coroutine runs, suspending the startup of the object until SomeCondition() returns true.
Is this legal because Start() is considered a message and can return either void (most common) or an IEnumerator to be treated as a coroutine?
This approach seems cleaner and more readable. Is there an advantage or disadvantage to it over the more common:
void Start() {
StartCoroutine(DoStart());
}
Thanks in advance!
That's weird, I could have sworn it used to say that in the documentation - as well as some other functions; and some $$anonymous$$onoBehaviour functions had it in their documentation that they explicitly couldn't be coroutines.
You may want to ask the forums and see if the staff has anything to say about the documentation.
The documentation did indicate this at one time (in the not so distant past). Other things have also been stripped from the documentation. For example, the docs used to say whether a "class" was a struct or not. In general things that happen once or occasionally can be IEnumerators but things that can happen every frame cannot. For example OnCollisionEnter can be an IEnumerator, but OnCollisionStay cannot, and Start can be, but Update cannot.
@robertbu: actually most callbacks i looked up still has the information if it can be a coroutine or not. However that class / struct thing still bothers me. Even i know most (if not all) yet Unity keeps adding new stuff and i have to look them up in ILSpy since the docs don't give that information. That's really sad.
I wanted to add that I found this use in the documentation here:
https://docs.unity3d.com/ScriptReference/AudioSource-clip.html
Guys, Does the first snippet (with while loop) essentially mean I can delay start-up stuff for as long as I want? For example, if my condition held for 10 seconds, would that mean the startup code would begin after 10 seconds whereas Update() would have obviously started immediately? Have I got the usage of IEnumerator Start() right?
Answer by Bunny83 · Jul 23, 2014 at 04:16 PM
Most Unity callbacks can be coroutines. Unity automatically starts it as coroutine if it returns an IEnumerator. Only a few can't be a coroutine. Most commonly: Awake, Update, LateUpdate, FixedUpdate, OnGUI, OnEnable, OnDisable, OnDestroy. I probably forgot some others, however it's usually stated for each callback if it can be a coroutine or not.
Your answer should be in the official Unity documentation, because as far as I've looked, it's not mentioned anywhere. You say that it's usually stated for each callback it if can be a coroutine or not, but I've yet to be able to find the source for that.
It actually was. Strangely the documentation of Start doesn't mention it anymore. However for example on the On$$anonymous$$ouseDown documentation page you can see the sentence:
On$$anonymous$$ouseDown can be a co-routine.
Likewise on the Awake page we can read:
Awake cannot be a co-routine.
The documentation get changed frequently and this information isn't consistently given for each callback. Just check the documentation yourself. Almost all "messages" either state that it can or can't be a coroutine. However specifically Start, Awake, Update, FixedUpdate, LateUpdate doesn't seem to have this information anymore.
Answer by spokrock · Feb 11, 2018 at 03:18 AM
It allows for any long running processes to complete during the start call before passing back control to the run loop to commence the Update calls...
Answer by Xtro · Jul 23, 2014 at 04:06 PM
I remember I did read that standard events like start and update can be co-routines in the past. But it was too long time ago and I was very new to unity. So I'm not sure 100%.
These days, as far as I know, standard event can't / shouldn't be co-routines. If we need a co-routine, we should start it with StartCoroutine() in the start or update events.
Update never could be a coroutine and this behaviour hasn't changed since at least Unity 2.6. In general it's more clear to seperate coroutines from Unity callbacks, but you don't have to. It's actually the other way round, it's a feature they have implemented on purpose.