Menu
CoddyTech

Wachsen

Lektion 8 von 14 im Kurs Unity-Spiel: 3D-Snake von Coddy.

Beim Fressen wird die Schlange um ein Segment länger. Das neue Segment kommt an die Stelle, an der sich das Ende des Schwanzes vor dem Schritt befand: Der Schwanz bewegt sich vorwärts, und das neue Segment füllt das Feld, das das Ende freigegeben hat. So wächst die Schlange von hinten.

Dieses Feld ist frei, sobald sich der Schwanz bewegt hat, also merke es dir zuerst. Wenn der Kopf dann das Futter erreicht hat, instanziiere dort ein Segment und füge es der Liste hinzu, damit es sich ab dem nächsten Schritt mitbewegt. Ein Segment, das erstellt, aber nicht hinzugefügt wird, bewegt sich nie. Ein Zug hängt auf dieselbe Weise hinten einen Waggon an:

Vector3 back = wagons[wagons.Count - 1].position;
// ... der Zug fährt weiter ...
Transform wagon = Instantiate(wagonPrefab, back, Quaternion.identity);
wagons.Add(wagon);

Lass die Schlange wachsen, bevor du Eat() aufrufst. Eat() bewegt das Futter, und in der nächsten Lektion wird es so angepasst, dass es nach einem Feld sucht, das die Schlange nicht belegt – einschließlich des neuen Segments.

challenge icon

Aufgabe

Mittel

Die Szene setzt segmentPrefab von Snake auf einen Würfel wie den Schwanz.

  1. Füge public Transform segmentPrefab; hinzu.
  2. Speichere in Step(), bevor sich der Schwanz bewegt, die Zelle des letzten Schwanzsegments in Vector3 tailEnd (die Zelle des Kopfes, wenn der Schwanz leer ist).
  3. Wenn der Kopf auf Futter ist, instanziiere segmentPrefab an tailEnd und füge es zu tail hinzu. Rufe dann Eat() auf.

Drücke auf Play und friss ein paar Futterstücke, dann drücke auf Check.

Probier es selbst

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

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // Sekunden zwischen zwei Schritten
    public int edge = 7;         // die Felder des Spielfelds reichen von -edge bis edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    private float timer;
    private Vector3 direction = Vector3.right;       // die Richtung, in die sich der Kopf beim letzten Schritt bewegt hat
    private Vector3 nextDirection = Vector3.right;   // die Richtungsänderung, die auf den nächsten Schritt wartet

    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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Unity-Spiel: 3D-Snake