Source file unity-csharp/arcade-classics/pac-man-lite/PacPlayer.cs from the GDnD code examples. Download raw file

// GDnD wiki example
// Demonstrates: buffered grid input on top of the shared mover, plus eating pellets on arrival
// Related pages: [[overview-arcade-classics-as-learning-projects]], [[unity-input]]
 
using UnityEngine;
 
// The player buffers the latest pressed direction every frame and turns as soon
// as that direction opens up — the responsive "pre-turn" feel of Pac-Man. Eating
// happens when it arrives on a cell.
public class PacPlayer : GridMover
{
    private Vector2Int buffered = Vector2Int.zero;
    private PacManGame game;
 
    public void Bind(PacManGame owner)
    {
        game = owner;
    }
 
    protected override void OnTick()
    {
        if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W)) buffered = Vector2Int.up;
        else if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S)) buffered = Vector2Int.down;
        else if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A)) buffered = Vector2Int.left;
        else if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D)) buffered = Vector2Int.right;
    }
 
    protected override Vector2Int ChooseDirection(Vector2Int cell, Vector2Int dir)
    {
        // Prefer the buffered turn; otherwise keep going; otherwise stop at the wall.
        if (buffered != Vector2Int.zero && maze.IsWalkable(cell + buffered)) return buffered;
        if (dir != Vector2Int.zero && maze.IsWalkable(cell + dir)) return dir;
        return Vector2Int.zero;
    }
 
    protected override void OnArrived(Vector2Int cell)
    {
        switch (maze.EatPellet(cell))
        {
            case MazeGrid.Pellet.Power:
                game.OnPowerPelletEaten();
                break;
            case MazeGrid.Pellet.Normal:
                game.OnPelletEaten();
                break;
        }
    }
}