Menu
CoddyTech

Хвост

Урок 7 из 14 курса Игра на Unity: 3D-змейка на Coddy.

Хвост — это список сегментов, List<Transform> tail, от сегмента сразу за головой, tail[0], до конца. В сцене змейка начинается с двух сегментов — Tail1 и Tail2, заданных в Inspector.

На каждом шаге каждый сегмент занимает клетку сегмента перед ним, а tail[0] занимает клетку головы. Порядок важен. Если двигаться от головы, tail[1] скопирует клетку, в которую уже переместился tail[0], и весь хвост соберётся в одной клетке. Если двигаться с конца, каждый сегмент копирует клетку, которая ещё не изменилась. Пассажиры, пересаживающиеся на одно место назад, перемещаются по тому же принципу:

string[] seats = { "Ana", "Ben", "Cy" };
for (int i = seats.Length - 1; i > 0; i--)
{
    seats[i] = seats[i - 1];
}
seats[0] = "Dee";   // Dee, Ana, Ben

Голова перемещается последней, когда tail[0] уже занял её прежнюю клетку.

challenge icon

Задание

Средне
  1. Добавь using System.Collections.Generic; и public List<Transform> tail = new List<Transform>();. Сцена заполняет его объектами Tail1 и Tail2.
  2. В Step(), непосредственно перед перемещением головы, перемести хвост: каждый сегмент, начиная с заднего, занимает клетку сегмента перед ним, а tail[0] занимает клетку головы.

Нажми Играть и управляй змейкой: хвост следует по пути головы. Затем нажми Проверить.

Попробуйте сами

using UnityEngine;
using UnityEngine.InputSystem;

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // секунды между двумя шагами
    public int edge = 7;         // клетки игрового поля простираются от -edge до edge
    public bool alive = true;
    private float timer;
    private Vector3 direction = Vector3.right;       // направление движения головы на предыдущем шаге
    private Vector3 nextDirection = Vector3.right;   // поворот, ожидающий следующего шага

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

        transform.position = next;

        if (GameManager.Instance.IsFood(next))
        {
            GameManager.Instance.Eat();
        }
    }

    void Die()
    {
        alive = false;
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Игра на Unity: 3D-змейка