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

Jedes Futterstück fügt dem Schwanz ein Segment hinzu.

  1. Füge in Snake public Transform segmentPrefab; hinzu (die Szene verknüpft es).
  2. Behalte in Step() vor der Bewegung des Schwanzes Vector3 tailEnd bei: die Zelle des letzten Segments oder, wenn der Schwanz leer ist, die Zelle des Kopfes.
  3. Füge beim Fressen Instantiate(segmentPrefab, tailEnd, Quaternion.identity) zu tail hinzu und rufe dann Eat() auf.

Drücke auf „Spielen“ und friss ein paar Futterstücke: Die Schlange wächst jedes Mal um einen Würfel. Drücke dann auf „Prüfen“.

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;
    }
}

Alle Lektionen in Unity-Spiel: 3D-Snake

Übe selbstständig: Unity-Playground