Menu
CoddyTech

Crescere

Lezione 8 di 14 del corso Gioco in Unity: Snake 3D di Coddy.

Mangiare fa diventare il serpente più lungo di un segmento. Il nuovo segmento va dove si trovava la punta della coda prima del passo: la coda avanza e il nuovo segmento occupa la cella lasciata libera dalla punta, così il serpente cresce dalla coda.

Quella cella non c’è più una volta che la coda si è spostata, quindi ricordala prima. Poi, quando la testa ha raggiunto il cibo, istanzia un segmento in quel punto e aggiungilo all’elenco, così dal passo successivo seguirà gli altri. Un segmento che viene creato ma non aggiunto non si muove. Un treno aggiunge un vagone in coda allo stesso modo:

Vector3 back = wagons[wagons.Count - 1].position;
// ... il treno prosegue ...
Transform wagon = Instantiate(wagonPrefab, back, Quaternion.identity);
wagons.Add(wagon);

Fai crescere il serpente prima di chiamare Eat(). Eat() sposta il cibo e, nella lezione successiva, il serpente cercherà una cella che non occupa, compresa quella del nuovo segmento.

challenge icon

Sfida

Medio

La scena imposta segmentPrefab di Snake su un cubo come quelli della coda.

  1. Aggiungi public Transform segmentPrefab;.
  2. In Step(), prima che la coda si muova, conserva la cella dell'ultimo segmento della coda in Vector3 tailEnd (la cella della testa quando la coda è vuota).
  3. Quando la testa è sul cibo, istanzia segmentPrefab su tailEnd e aggiungilo a tail, poi chiama Eat().

Premi Play e mangiane alcuni, poi premi Check.

Provalo tu

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // secondi tra due passi
    public int edge = 7;         // le celle della griglia vanno da -edge a edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    private float timer;
    private Vector3 direction = Vector3.right;       // la direzione in cui si è mossa la testa nell'ultimo passo
    private Vector3 nextDirection = Vector3.right;   // la svolta in attesa del prossimo passo

    void Update()
    {
        if (!alive) return;

        Keyboard keyboard = Keyboard.current;
        if (keyboard != null)
        {
            if (keyboard.upArrowKey.wasPressedThisFrame || keyboard.wKey.wasPressedThisFrame) Turn(Vector3.forward);
            if (keyboard.downArrowKey.wasPressedThisFrame || keyboard.sKey.wasPressedThisFrame) Turn(Vector3.back);
            if (keyboard.leftArrowKey.wasPressedThisFrame || keyboard.aKey.wasPressedThisFrame) Turn(Vector3.left);
            if (keyboard.rightArrowKey.wasPressedThisFrame || keyboard.dKey.wasPressedThisFrame) Turn(Vector3.right);
        }

        timer += Time.deltaTime;
        if (timer >= tick)
        {
            timer -= tick;
            Step();
        }
    }

    void Turn(Vector3 newDirection)
    {
        if (newDirection != -direction)
        {
            nextDirection = newDirection;
        }
    }

    void Step()
    {
        direction = nextDirection;
        Vector3 next = transform.position + direction;
        if (Mathf.Abs(next.x) > edge || Mathf.Abs(next.z) > edge)
        {
            Die();
            return;
        }

        for (int i = tail.Count - 1; i > 0; i--)
        {
            tail[i].position = tail[i - 1].position;
        }
        if (tail.Count > 0)
        {
            tail[0].position = transform.position;
        }
        transform.position = next;

        if (GameManager.Instance.IsFood(next))
        {
            GameManager.Instance.Eat();
        }
    }

    void Die()
    {
        alive = false;
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Gioco in Unity: Snake 3D