Menu
CoddyTech

Ostacoli

Lezione 9 di 20 del corso Gioco Unity: Corsie nel cielo di Coddy.

Ora la strada ha bisogno di qualcosa da schivare. Ogni pezzo riceve un ostacolo al centro, in una corsia casuale. Se ne occupa un metodo, Fill, chiamato per ogni nuovo pezzo in Start e di nuovo ogni volta che un pezzo torna in testa.

I primi due pezzi restano vuoti, per dare un momento al giocatore: Road conta i pezzi che ha riempito in made.

void Fill(Transform chunk)
{
    made++;
    if (made <= safeChunks) return;

    int lane = Random.Range(-1, 2);
    Place(chunk, barrierPrefab, lane, 0.5f, 0f);
}

Random.Range(-1, 2) è -1, 0 o 1: con i numeri interi il secondo numero non viene mai scelto.

Un pezzo riciclato conserva ancora il suo vecchio ostacolo. Clear distrugge ogni elemento figlio che ha un tag. Il pavimento, le linee tratteggiate e i bordi sono Untagged, quindi restano:

void Clear(Transform chunk)
{
    foreach (Transform child in chunk)
    {
        if (!child.CompareTag("Untagged")) Destroy(child.gameObject);
    }
}
challenge icon

Sfida

Facile
  1. In Road, aggiungi public GameObject barrierPrefab;, public int safeChunks = 2; e private int made;.
  2. Scrivi Place(chunk, prefab, lane, y, z): crea il prefab in chunk.position + new Vector3(lane * laneWidth, y, z) con prefab.transform.rotation, come figlio del pezzo.
  3. Scrivi Fill e Clear come sopra.
  4. Chiama Fill(chunk) per ogni pezzo in Start e Clear(chunk); Fill(chunk); quando un pezzo raggiunge la parte anteriore.

Provalo tu

using UnityEngine;

public class Runner : MonoBehaviour
{
    public float laneWidth = 2.5f;
    public float laneSpeed = 16f;
    public float jumpHeight = 1.6f;
    public float gravity = -40f;
    public float slideTime = 0.7f;

    public int lane;

    private CharacterController controller;
    private float fallSpeed;
    private float slide;

    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) lane = Mathf.Max(-1, lane - 1);
        if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow)) lane = Mathf.Min(1, lane + 1);
        bool jump = Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space);
        if (jump && controller.isGrounded)
        {
            fallSpeed = Mathf.Sqrt(jumpHeight * -2f * gravity);
            StopSlide();
        }
        if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && controller.isGrounded)
        {
            slide = slideTime;
            Resize(0.5f);
        }

        if (slide > 0f)
        {
            slide -= Time.deltaTime;
            if (slide <= 0f) StopSlide();
        }

        if (controller.isGrounded && fallSpeed < 0f) fallSpeed = -2f;
        fallSpeed += gravity * Time.deltaTime;

        float targetX = lane * laneWidth;
        float x = Mathf.MoveTowards(transform.position.x, targetX, laneSpeed * Time.deltaTime);
        Vector3 move = new Vector3(x - transform.position.x, fallSpeed * Time.deltaTime, 0f);
        controller.Move(move);
    }

    void StopSlide()
    {
        if (transform.localScale.y < 1f) Resize(1f);
        slide = 0f;
    }

    void Resize(float height)
    {
        controller.enabled = false;
        transform.position += Vector3.up * (height - transform.localScale.y);
        transform.localScale = new Vector3(1f, height, 1f);
        controller.enabled = true;
    }
}

Tutte le lezioni di Gioco Unity: Corsie nel cielo

Esercitati da solo: Playground Unity