Menu
CoddyTech

Loops em corrotinas

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

Um loop com um yield return dentro é executado ao longo de vários frames, porque cada iteração pausa antes da próxima. Com WaitForSeconds, o loop repete algo em intervalos regulares. Esta sirene pisca 3 vezes:

IEnumerator Flash()
{
    for (int i = 0; i < 3; i++)
    {
        lamp.enabled = true;
        yield return new WaitForSeconds(0.2f);
        lamp.enabled = false;
        yield return new WaitForSeconds(0.2f);
    }
}

Com yield return null, o loop faz um pouco a cada frame até que sua condição seja satisfeita, que é como uma coroutine anima algo. Este balão, com uma escala de 1, cresce 0.5 por segundo até sua escala chegar a 2 e, então, informa:

IEnumerator Inflate()
{
    while (transform.localScale.x < 2f)
    {
        transform.localScale += Vector3.one * 0.5f * Time.deltaTime;
        yield return null;
    }
    Debug.Log("Full");
}

Time.deltaTime funciona aqui como em Update(): a coroutine é retomada uma vez por frame, e a linha após o loop só é executada quando o loop termina. Sem o yield, o loop inteiro é executado em um único frame, e o balão fica cheio de uma vez. Um loop while (true) funciona bem em uma coroutine, desde que produza um yield em cada iteração; sem um yield, ele nunca devolve o controle ao frame, e o editor do Unity congela.

challenge icon

Desafio

Fácil

Escreva Ride para que a grade faça um percurso completo.

  1. Defina Vector3 up = down + Vector3.up * height;. Enquanto while (transform.position != up), mova com Vector3.MoveTowards(transform.position, up, speed * Time.deltaTime) e yield return null;.
  2. Registre Open e, em seguida, yield return new WaitForSeconds(1f);.
  3. Faça o percurso de volta até down da mesma maneira e, em seguida, registre Closed.

Pressione “Jogar” e a tecla Espaço: o portão sobe, espera e fecha. Depois, clique em “Verificar”.

Experimente você mesmo

using System.Collections;
using UnityEngine;

public class Portcullis : MonoBehaviour
{
    public float speed = 1.5f;
    public float height = 3f;
    Vector3 down;

    void Start()
    {
        down = transform.position;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Ride());
        }
    }

    IEnumerator Ride()
    {
        // Suba height unidades à velocidade speed e registre Open, permaneça por 1 segundo, desça novamente e registre Closed
        yield return null;
    }
}

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

Pratique por conta própria: Playground de Unity