Menu
CoddyTech

No U-Turns

Lesson 3 of 14 in Coddy's Unity Game: Snake 3D course.

A snake that turns straight back runs into its own neck, so a turn to the opposite of the way it is going is ignored. The opposite of a direction is its negative: while the snake moves right, -direction is Vector3.left.

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

Comparing with direction is not enough while a press changes direction at once. Moving right, a player taps up and then left inside one tick. Up is allowed. Left is then checked against up, the turn that has not happened yet, and allowed too, so the next step goes left, straight back over the neck.

The fix keeps two directions. direction is the way the head moved on its last step; nextDirection is the turn waiting for the next step. A key changes nextDirection, but only after comparing the turn with direction, and the step begins by making the waiting turn real. In the case above, left is compared with right, the way the head really moves, and dropped.

challenge icon

Challenge

Easy
  1. Add private Vector3 nextDirection = Vector3.right;, the turn waiting for the next step.
  2. Write void Turn(Vector3 newDirection): it sets nextDirection to newDirection, unless newDirection is the opposite of direction.
  3. In Update(), each key calls Turn with its direction instead of setting direction.
  4. At the start of Step(), set direction to nextDirection.

Press Play and try to turn back, then press Check.

Try it yourself

using UnityEngine;
using UnityEngine.InputSystem;

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // seconds between two steps
    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 iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Unity Game: Snake 3D