Menu
CoddyTech

Interrompendo corrotinas

Parte da seção Física e Jogabilidade do Journey de Unity da Coddy. Lição 26 de 71.

StartCoroutine retorna uma Coroutine, uma referência à corrotina que iniciou. Guarde-a em um campo, e StopCoroutine(handle) interrompe essa corrotina no ponto em que está pausada: as linhas depois do yield nunca são executadas. StopAllCoroutines() interrompe todas as corrotinas iniciadas pelo script. A tecla Espaço liga e desliga este alarme:

Coroutine beeping;

void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        if (beeping == null)
        {
            beeping = StartCoroutine(Beep());
        }
        else
        {
            StopCoroutine(beeping);
            beeping = null;
        }
    }
}

IEnumerator Beep()
{
    while (true)
    {
        Debug.Log("Beep");
        yield return new WaitForSeconds(1f);
    }
}

O campo não é limpo quando a corrotina é interrompida, então o alarme o define novamente como null, e na próxima vez que você pressionar Espaço, o programa sabe que nada está em execução. Duas maneiras que parecem corretas não funcionam. StopCoroutine(Beep()) chama Beep() novamente, o que cria uma nova corrotina ainda não iniciada, e interrompe essa corrotina; por isso, o alarme continua apitando. E enabled = false desativa o Update() do script, mas as corrotinas continuam em execução. Uma corrotina termina quando é interrompida por meio de sua referência ou por StopAllCoroutines(), quando chega à última linha ou quando seu GameObject é desativado com SetActive(false) ou destruído.

challenge icon

Desafio

Fácil

Faça um clique desarmar a bomba sem desativar o script.

  1. Adicione um campo Coroutine fuse;. Ao pressionar Espaço, defina fuse = StartCoroutine(Fuse());.
  2. Ao clicar, substitua enabled = false;: quando fuse != null, chame StopCoroutine(fuse);, defina fuse = null; e registre Defused.

Pressione “Jogar”, pressione Espaço e, em seguida, clique: o Console mostra Defused e a bomba permanece. Depois, pressione “Verificar”.

Experimente você mesmo

using System.Collections;
using UnityEngine;

public class Bomb : MonoBehaviour
{
    public float fuseTime = 3f;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Fuse());
        }
        if (Input.GetMouseButtonDown(0))
        {
            enabled = false;
            Debug.Log("Defused");
        }
    }

    IEnumerator Fuse()
    {
        Debug.Log("Fuse lit");
        yield return new WaitForSeconds(fuseTime);
        Debug.Log("Boom");
        Destroy(gameObject);
    }
}

Todas as lições de Física e Jogabilidade

Pratique por conta própria: Playground de Unity