Source file unity-csharp/arcade-classics/snake/SnakeInput.cs from the GDnD code examples. Download raw file

// GDnD wiki example
// Demonstrates: buffering a turn between simulation steps and rejecting 180-degree reversals
// Related pages: [[overview-arcade-classics-as-learning-projects]], [[unity-input]]
 
using UnityEngine;
 
// Snake reads input every frame but only turns once per simulation step. This
// script buffers the most recent valid request and hands it to the game when the
// next step fires. Directions are grid vectors (Vector2Int), not world motion.
public class SnakeInput : MonoBehaviour
{
    private Vector2Int currentDirection = Vector2Int.right;
    private Vector2Int bufferedDirection = Vector2Int.right;
 
    private void Update()
    {
        Vector2Int requested = ReadRequestedDirection();
 
        // Ignore no input and any reversal straight back into the snake's neck.
        if (requested != Vector2Int.zero && requested != -currentDirection)
        {
            bufferedDirection = requested;
        }
    }
 
    private Vector2Int ReadRequestedDirection()
    {
        if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W)) return Vector2Int.up;
        if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S)) return Vector2Int.down;
        if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A)) return Vector2Int.left;
        if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D)) return Vector2Int.right;
        return Vector2Int.zero;
    }
 
    // Called once per simulation step: locks in the buffered turn and returns it.
    public Vector2Int ConsumeDirection()
    {
        currentDirection = bufferedDirection;
        return currentDirection;
    }
 
    public void ResetDirection()
    {
        currentDirection = Vector2Int.right;
        bufferedDirection = Vector2Int.right;
    }
}