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.
Aufgabe
MittelDie Szene setzt segmentPrefab von Snake auf einen Würfel wie den Schwanz.
- Füge
public Transform segmentPrefab;hinzu. - Speichere in
Step(), bevor sich der Schwanz bewegt, die Zelle des letzten Schwanzsegments inVector3 tailEnd(die Zelle des Kopfes, wenn der Schwanz leer ist). - Wenn der Kopf auf Futter ist, instanziiere
segmentPrefabantailEndund füge es zutailhinzu. Rufe dannEat()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;
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.