AI Systems Showcase

A modular AI framework built in Unity (C#) featuring steering behaviours, flocking systems, utility-based decision making, and multiple pathfinding algorithms. Designed with extensibility, performance, and debugging clarity in mind.

Role: Gameplay / AI Programmer
Engine: Unity (C#)

Technical Overview

Modular Steering Architecture

Built a composable steering framework where behaviours calculate forces independently and blend via weighted accumulation.

Flocking Implementation

Implemented Alignment, Cohesion, and Separation using spatial queries, field-of-view filtering, and weighted steering forces.

Utility-Based AI

Designed a scalable utility system allowing agents to dynamically prioritise combat, support, flee, and exploration behaviours.

Advanced Pathfinding

Implemented Dijkstra, A*, and Jump Point Search (JPS) with diagonal control and heuristic configuration.

Collision Avoidance

Velocity-scaled whisker raycasts detect penetration depth and apply corrective steering forces with debug visualisation.

Runtime Debug Tooling

Integrated Gizmos and grid colouring for live inspection of steering, obstacle detection, and path expansion.

Steering Behaviour Framework

Core movement system where each behaviour computes a steering force and blends into the final velocity.

Force Calculation Model

All behaviours calculate a desired velocity and subtract the current velocity to produce a steering force. Forces are weight-scaled and blended.


// Steering formula
Vector2 steering = desiredVelocity - currentVelocity;
return steering * weight;

This structure allows behaviours to be enabled/disabled dynamically by higher-level AI systems.

Flocking (Alignment, Cohesion, Separation)

Implemented Reynolds-style flocking using physics queries, dot-product FOV filtering, and inverse-distance weighting.

Alignment

Agents average neighbour headings and steer toward the combined direction to maintain group coherence.

Cohesion

Agents calculate the centre of mass of nearby neighbours and apply a seek force toward that position.

Separation

Repulsion force is calculated using inverse-distance weighting to prevent overlap and jitter while preserving smooth motion.


// Neighbour detection
Collider2D[] agents =
Physics2D.OverlapCircleAll(transform.position, range, agentLayerMask);
Obstacle Avoidance (Whisker System)

Velocity-scaled feelers project forward to detect obstacles and compute penetration-based repulsion forces.

Dynamic Feeler Length

Feeler length interpolates based on current speed, allowing faster agents to anticipate collisions earlier.


// Raycast detection
RaycastHit2D hit =
Physics2D.Raycast(origin, direction, length, layerMask);

Debug colours visualise hit states directly in the editor.

Utility-Based Decision Making

Replaced rigid FSM transitions with dynamic utility scoring to allow emergent prioritisation.

Decision Pipeline

Sense → Calculate Utilities → Choose Highest Score → Activate Steering.


// Utility selection
foreach (var pair in utilityDictionary)
{
    if (pair.Value > bestScore)
        currentState = pair.Key;
}

State cooldowns prevent oscillation and improve behavioural stability.

Pathfinding Systems

Implemented multiple grid-based pathfinding algorithms with configurable heuristics and diagonal rules.

Dijkstra

Uniform cost expansion guaranteeing shortest path.

A*

Combined gCost and heuristic (Manhattan / Octile) for optimal and efficient path resolution.

Jump Point Search

Directional pruning reduces node expansion by identifying forced neighbours and symmetric paths.


// Cheapest node selection
return nodes.OrderBy(n => n.fCost).First();

Performance & Optimization

Engineering Challenges Solved