Skip to content

Instantly share code, notes, and snippets.

@jesterswilde
Created August 27, 2025 06:55
Show Gist options
  • Select an option

  • Save jesterswilde/2ccb36b56c512fcffc4d2a59de45914c to your computer and use it in GitHub Desktop.

Select an option

Save jesterswilde/2ccb36b56c512fcffc4d2a59de45914c to your computer and use it in GitHub Desktop.
Unity Controls Helper
using System;
using UnityEngine;
[Flags]
public enum DPad : byte
{
None = 0,
Up = 1 << 0,
Down = 1 << 1,
Left = 1 << 2,
Right = 1 << 3
}
public enum Directions
{
Up, Down, Left, Right,
UpLeft, UpRight, DownLeft, DownRight
}
public class Controls : MonoBehaviour
{
static Controls t;
public static Controls T => t;
static readonly KeyCode[] UpKeys = { KeyCode.W, KeyCode.UpArrow };
static readonly KeyCode[] DownKeys = { KeyCode.S, KeyCode.DownArrow };
static readonly KeyCode[] LeftKeys = { KeyCode.A, KeyCode.LeftArrow };
static readonly KeyCode[] RightKeys = { KeyCode.D, KeyCode.RightArrow };
public static bool IsPushingDirection(Directions dir)
=> Matches(dir, GetPad(Input.GetKey), only:false);
public static bool JustPushedDirection(Directions dir)
// “just pushed” for a direction means all its component keys transitioned down,
// while we don’t require exclusivity.
=> Matches(dir, GetPad(Input.GetKeyDown), only:false);
public static bool IsPushingOnlyDirection(Directions dir)
=> Matches(dir, GetPad(Input.GetKey), only:true);
public static bool JustPushedOnlyDirection(Directions dir)
=> Matches(dir, GetPad(Input.GetKeyDown), only:true);
// Build a DPad bitmask using any Input.* predicate
static DPad GetPad(Func<KeyCode, bool> check)
{
DPad pad = DPad.None;
if (Any(UpKeys, check)) pad |= DPad.Up;
if (Any(DownKeys, check)) pad |= DPad.Down;
if (Any(LeftKeys, check)) pad |= DPad.Left;
if (Any(RightKeys, check)) pad |= DPad.Right;
return pad;
}
static bool Any(KeyCode[] keys, Func<KeyCode, bool> check)
{
for (int i = 0; i < keys.Length; i++)
if (check(keys[i])) return true;
return false;
}
static DPad RequiredMask(Directions dir) => dir switch
{
Directions.Up => DPad.Up,
Directions.Down => DPad.Down,
Directions.Left => DPad.Left,
Directions.Right => DPad.Right,
Directions.UpLeft => DPad.Up | DPad.Left,
Directions.UpRight => DPad.Up | DPad.Right,
Directions.DownLeft => DPad.Down | DPad.Left,
Directions.DownRight => DPad.Down | DPad.Right,
_ => DPad.None
};
static bool Matches(Directions dir, DPad pad, bool only)
{
var need = RequiredMask(dir);
bool hasAll = (pad & need) == need;
if (!hasAll) return false;
return !only || pad == need;
}
void Awake() {
if (t != null) { Destroy(this); return; }
t = this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment