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