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
MittelJedes Futterstück fügt dem Schwanz ein Segment hinzu.
- Füge in
Snakepublic Transform segmentPrefab;hinzu (die Szene verknüpft es). - Behalte in
Step()vor der Bewegung des SchwanzesVector3 tailEndbei: die Zelle des letzten Segments oder, wenn der Schwanz leer ist, die Zelle des Kopfes. - Füge beim Fressen
Instantiate(segmentPrefab, tailEnd, Quaternion.identity)zutailhinzu und rufe dannEat()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