The body of 'enlargeBalloon.Update()' cannot be an iterator block because 'void' is not an iterator interface type

How can I fix this?

1 comments

@DMGregory 2019-01-12 11:15:39

It looks like you're trying to use Update as a Coroutine - a procedure that can suspend itself midway-through and pass control back to the game loop to keep updating/rendering frames, then resume where it left off later.

You can tell something is a Coroutine if it uses the yield return construct to pause itself like this anywhere.

To make a method a coroutine, you need to change its signature from:

void MethodName() {
...

to:

IEnumerator MethodName() {
...

The reason is that under the hood, running a Coroutine is actually creating an object called an iterator that implements the IEnumerator interface — something we can call MoveNext() on to make it step through a sequence of values/actions. That's how the engine pumps the coroutine each time it needs to be resumed. Instead of returning nothing (void), calling the method returns this new iterator object, so the return type needs to match this.

Now, there's a bit of a danger in calling Update as a coroutine: Update is already called every frame!

So if some of those calls don't end in the same frame, but continue/suspend for some time, they could pile up very quickly. In this example, if the player rapidly tapped their mouse button for a second at 60fps, you could have increased your size 30 times over and have 30 copies of the coroutine waiting to resume.

Fortunately, the engine knows what a disaster this would be, and won't let us do it. Many MonoBehaviour messages are allowed to be marked as IEnumerator and called as coroutines, but Update is not one of them.

MonoBehaviour messages that can't be Coroutines include:

Initialization: Awake, OnEnable

Core update loop: Update, LateUpdate, FixedUpdate, OnGUI

Shutdown: OnDisable, OnDestroy (Obviously, after calling one of these, the object is likely not eligible to keep running a Coroutine the next frame)

So, what can we do instead?

Well, since Update is already running every frame, we don't need a while loop to keep iterating. We can do that with the game loop itself, changing our while to a simple if: