Crecer
Lección 8 de 14 del curso Juego de Unity: Serpiente 3D de Coddy.
Al comer, la serpiente crece un segmento. El nuevo segmento aparece donde estaba el extremo de la cola antes del movimiento: la cola avanza y el nuevo segmento ocupa la celda que ha dejado libre el extremo, así que la serpiente crece por detrás.
Esa celda desaparece cuando la cola se ha movido, así que recuérdala primero. Después, cuando la cabeza haya llegado a la comida, instancia un segmento allí y añádelo a la lista para que empiece a seguirla en el siguiente movimiento. Un segmento que se crea pero no se añade nunca se mueve. Un tren añade un vagón por detrás de la misma manera:
Vector3 back = wagons[wagons.Count - 1].position;
// ... el tren sigue avanzando ...
Transform wagon = Instantiate(wagonPrefab, back, Quaternion.identity);
wagons.Add(wagon);Haz crecer la serpiente antes de llamar a Eat(). Eat() mueve la comida y, en la siguiente lección, haremos que busque una celda que la serpiente no ocupe, incluido el nuevo segmento.
Desafío
IntermedioCada alimento añade un segmento a la cola.
- En
Snake, añadepublic Transform segmentPrefab;(la escena lo vincula). - En
Step(), antes de que se mueva la cola, guardaVector3 tailEnd: la celda del último segmento o la celda de la cabeza cuando la cola está vacía. - Al comer alimento, añade
Instantiate(segmentPrefab, tailEnd, Quaternion.identity)ataily luego llama aEat().
Presiona «Jugar» y come unos cuantos: la serpiente crece un cubo cada vez. Después, presiona «Comprobar».
Pruébalo tú mismo
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class Snake : MonoBehaviour
{
public float tick = 0.15f; // segundos entre dos pasos
public int edge = 7; // las celdas del tablero van de -edge a edge
public bool alive = true;
public List<Transform> tail = new List<Transform>();
private float timer;
private Vector3 direction = Vector3.right; // la dirección en la que se movió la cabeza en su último paso
private Vector3 nextDirection = Vector3.right; // el giro pendiente para el próximo paso
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;
}
}
Todas las lecciones de Juego de Unity: Serpiente 3D
Practica por tu cuenta: Playground de Unity