Menu
CoddyTech

Без разворотов

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

Змея, которая сразу разворачивается назад, натыкается на собственную шею, поэтому поворот в направлении, противоположном текущему движению, игнорируется. Противоположное направление — это отрицательное направление: когда змея движется вправо, -direction — это Vector3.left.

Vector3 heading = Vector3.right;
Vector3 back = -heading;            // (-1, 0, 0), Vector3.left
bool reverse = Vector3.left == back;   // true

Сравнивать с direction недостаточно, если нажатие сразу меняет direction. Двигаясь вправо, игрок нажимает вверх, а затем влево в течение одного такта. Поворот вверх разрешён. Затем поворот влево проверяется относительно направления вверх — поворота, который ещё не произошёл, — и тоже разрешается, поэтому следующий шаг ведёт влево, прямо назад через шею.

Решение использует два направления. direction — направление, в котором голова двигалась на последнем шаге; nextDirection — поворот, ожидающий следующего шага. Нажатие клавиши меняет nextDirection, но только после сравнения поворота с direction, а шаг начинается с применения ожидающего поворота. В описанном выше случае направление влево сравнивается с направлением вправо — тем, в котором голова действительно движется, — и отбрасывается.

challenge icon

Задание

Легко
  1. Добавь private Vector3 nextDirection = Vector3.right; — поворот, ожидающий следующего шага.
  2. Напиши void Turn(Vector3 newDirection): эта функция задаёт nextDirection равным newDirection, если только newDirection не противоположен direction.
  3. В Update() каждая клавиша вызывает Turn со своим направлением вместо того, чтобы задавать direction.
  4. В начале Step() присвой direction значение nextDirection.

Нажми Играть и попробуй повернуть назад, затем нажми Проверить.

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

using UnityEngine;
using UnityEngine.InputSystem;

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // секунды между двумя шагами
    private float timer;
    private Vector3 direction = Vector3.right;

    void Update()
    {
        Keyboard keyboard = Keyboard.current;
        if (keyboard != null)
        {
            if (keyboard.upArrowKey.wasPressedThisFrame || keyboard.wKey.wasPressedThisFrame) direction = Vector3.forward;
            if (keyboard.downArrowKey.wasPressedThisFrame || keyboard.sKey.wasPressedThisFrame) direction = Vector3.back;
            if (keyboard.leftArrowKey.wasPressedThisFrame || keyboard.aKey.wasPressedThisFrame) direction = Vector3.left;
            if (keyboard.rightArrowKey.wasPressedThisFrame || keyboard.dKey.wasPressedThisFrame) direction = Vector3.right;
        }

        timer += Time.deltaTime;
        if (timer >= tick)
        {
            timer -= tick;
            Step();
        }
    }

    void Step()
    {
        transform.position += direction;
    }
}
quiz iconПроверьте себя

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

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