← Portfolio Saarth Kishore GitHub
Shipped

Case study · Personal project · Sep 2026 – Present

Motion Sense Game

A hands-free third-person action game — your webcam is the controller.

Motion Sense Game maps real-time hand gestures to full gameplay: walk, jump, slash, punch, blast, inventory, and a God of War–style orbit camera. A Python + MediaPipe vision stack classifies static poses and dynamic trajectories, then streams JSON events over a local WebSocket into Unity 6 — so computer vision and game systems stay fully decoupled and production-ready.

The hook

Controllers are great — until you want to play standing up with nothing in your hands. Motion Sense Game treats the webcam as a full input device: left hand owns locomotion and combat, right hand owns look and UI, and both work at the same time.

Control scheme

HandGestureGameplay
LeftTwo fingers down + motionWalk (camera-relative)
LeftTwo fingers curl upJump (ground-gated)
LeftOpen palm, fingers spreadBlast
LeftFingers together + swipeSlash
LeftFist + forward thrustPunch
RightFist + moveOrbit camera look
RightBack of hand + finger countInventory open / select
RightIndex pointer / thumbsAim cursor · accept / deny

Vision → game pipeline

  1. Capture — OpenCV webcam frames → MediaPipe Hand Landmarker (21 landmarks × up to 2 hands).
  2. Classify — pure functions for static poses; rolling buffers for walk / slash / punch / look deltas.
  3. Dispatch — priority state machine (inventory / combat / locomotion) emits small JSON events.
  4. Bridge — Python WebSocket server on ws://127.0.0.1:8765.
  5. Play — Unity client marshals events to the main thread and drives Rigidbody + orbit camera.

Same pattern as a hardware controller driver — gestures are just another input device.

Static vs dynamic gestures

The codebase keeps a hard split from day one: single-frame landmark shapes vs sequences over time. That separation is what keeps blast from stealing slash, and inventory from stealing walk when lighting or orientation is noisy.

Third-person camera

Right-hand fist look is not freelook FPS. The camera orbits the player at a fixed distance with shoulder bias, smooth follow, and pitch clamps — the same “stuck behind you” feel as God of War–style action games. Walking always moves along camera planar forward so look and locomotion stay aligned.

Hard problems solved

Black / feedback webcam frames

Forced 1280×720 and screen-in-camera loops killed the feed. Native resolution probing, buffer flush, and a small preview window fixed capture reliability on Windows.

Gesture collisions

Open palm was firing walk/slash. Split blast (spread fingers) vs slash (fingers together + swipe), locked walk to downward two-finger motion, and assigned left/right hand roles.

Unity not receiving look events

NumPy scalars crashed JSON encode; WebSocket callbacks ran off the main thread. Added JSON sanitization and a concurrent queue drained in Update.

Camera feel

First look implementation rotated like FPS. Rebuilt as a world-space orbit with look-at focus, shoulder offset, and camera-relative walk.

Stack & what I owned

Solo end-to-end: gesture research, MediaPipe pipeline, state machine, WebSocket protocol, Unity input router, third-person camera, and player feel systems.

Status

Full control loop shipped and playable: dual-hand gestures, combat events, inventory hooks, and third-person camera. Source on GitHub; next iteration is combat enemies, inventory loadouts, and a polished arena level.