A 2D pixel-art action platformer built in Unity for a Game Development class.
A state machine-driven movement controller with ~16 discrete states:
| State | Description |
|---|---|
| Idle/Walk/Run | Ground movement with velocity-based transitions |
| Jump Ascending/Cut | Variable jump height with apex tracking |
| Falling | Airborne state with gravity control |
| Dash | Horizontal burst with cooldown |
| Dash Fast Fall | Cancel vertical velocity during dash |
| Dash Cancel Vertical | Stop upward momentum mid-dash |
| Wall Slide | Slow descent along walls |
| Wall Jump (Asc/Cut/Fast Fall) | Three variants based on input |
| Slide | Quick ground-level evasion |
| Crouch | Defensive stance |
Key Files:
Assets/TidiMovementComponent2D/scripts/Core/PlayerSM.cs— Central singleton (PlayerSm.Instance) managing state machine, input, movement statsAssets/TidiMovementComponent2D/scripts/States/Player*StateSM.cs— Individual state implementationsAssets/TidiMovementComponent2D/scripts/Physics/MovementControllerSM.cs— Low-level physics: velocity, gravity, ground/wall detection, coyote time
TidiAnimInstance(base) →POIAnimInstance(game-specific)- Hash-based animation triggering via
Animator.StringToHash - Animation states:
StandingState,InAirState - Blended combat animations with directional input support
Key Files:
Assets/TidiMovementComponent2D/scripts/Animation/TidiAnimInstance.csAssets/PathOfTheInfected - Core/Scripts/Animation/POIAnimInstance.cs
Reset-Based Combat (RBC) with combo multipliers and perk subsystems:
| Component | Description |
|---|---|
| Input Capture | Attack buffering with configurable window |
| Timeline-Based Attacks | Startup → Active → Recovery phases |
| BlendSpace2D | Directional punch animations based on stick input |
| Combo Subsystem | Hit counters, speed/damage multipliers |
| RBC Subsystem | Cooldown resets on successful hits |
| Perk Subsystem | Passive bonuses from collected perks |
Combat Flags: CombatIntentFlags (input intents) and CombatFlags (active states) using [Flags] bitfields
Key Files:
Assets/PathOfTheInfected - Core/Scripts/Player/Combat/PlayerCombat.cs— Main orchestratorAssets/PathOfTheInfected - Core/Scripts/Combat/Subsystems/— Modular subsystemsAssets/PathOfTheInfected - Core/Scripts/Player/Combat/Attacks/— ScriptableObject attack definitions
- PlayerHealth — Damage reception, hit response, UI message broadcasting
- HitStopManager — Frame-freeze on impact for juice
- EnemyHealth — Enemy damage handling with death events
EnemyStateMachine
├── NoSpottableDetectedState → Wander/Patrol
├── SpottableDetectedState → Aggro/Chase
└── SpottableInAttackRangeState → Attack
| Enemy | Behavior |
|---|---|
| FlyingPuncher | Flying movement personality, melee punch attack |
| MeleePuncher | Ground-based chaser with touch/punch attacks |
| RangedEnemy | Projectile-based attacks from distance |
- EnemyBrainBase — Decision-making core
- EnemyFlyingBrainBase — Flying-specific logic
- MovementPersonality — Configurable movement params (speed, acceleration, aggro range)
- EnemySpottable — Player detection via raycasting/distance checks
- PlayerSpot — Player-side spot marker for enemy AI
- ISpottable — Interface for detectable entities
Key Files:
Assets/PathOfTheInfected - Core/Scripts/Enemy/— All enemy codeAssets/PathOfTheInfected - Core/Scripts/Enemy/Enemy brains/— Brain implementationsAssets/PathOfTheInfected - Core/Scripts/Enemy/States/— State definitions
| Component | Description |
|---|---|
| BossBrain | Phase-based Boss AI |
| BossPhase | Multi-phase combat with transition logic |
| BossCombatState | Attack patterns per phase |
| BossHealth | Phase triggers on HP thresholds |
Verlet integration-based 2D cloth simulation for scarf/hair:
| Feature | Description |
|---|---|
| Fixed Timestep | Accumulator with configurable substeps |
| Distance Constraints | Segment-to-segment length preservation |
| Bend Constraints | Angular resistance for stiffness |
| Shape Constraints | Anchor points for structure |
| Wind Forces | Environmental perturbation |
| Turn Impulse | Flick on player direction change |
Key Files:
Assets/TidiMovementComponent2D/scripts/Cloth/ClothController.cs— Main simulationAssets/TidiMovementComponent2D/scripts/Cloth/Data/ClothPoint.cs— Point data structure
| Effect | Description |
|---|---|
| GhostTrail | Afterimage trail during dash |
| Jump Particles | Ground dust on jump |
| WallSlide Particles | Wall friction sparks |
| Speed Particles | Motion blur effect at high velocity |
| Land Particles | Impact dust on landing |
Component-based UI architecture using Unity's UI Toolkit:
| Layer | Responsibility |
|---|---|
| UIView | VisualElement subclass with Show()/Hide() lifecycle |
| UIScreen | Controller logic (Init, Start, Tick, FixedTick, Dispose) |
| UIRouter | Routes controllers to views, manages lifecycle |
| UIComponent | Decorator pattern for reusable UI behaviors |
Examples:
ControllerIconDecorator— Dynamically swaps controller button iconsUIButtonComponent— Abstracts button click handling
Key Files:
Assets/TidiModularUISystem/Scripts/Core/— Core frameworkAssets/PathOfTheInfected - UI/Scripts/— Game-specific UI implementationAssets/PathOfTheInfected - UI/Scripts/Router/POIRouter.cs— Game UI router
Typed event bus for decoupled communication:
// Publish
TidiGameplayMessagingSubsystem.Instance.Broadcast<OnPlayerHealthChangedUI, HealthPayload>(payload);
// Subscribe
TidiGameplayMessagingSubsystem.Instance.Listen<PlayerHealthChannel, HealthPayload>(OnHealthChanged);Features:
- Zero-boxing payload dispatch via
ArrayPool<T> - Re-entrant safe (queued delivery)
- Signal-only channels (no payload) and payload channels
- IDisposable unsubscription tokens
Key Files:
Assets/TidiGameplayMessaging/Core/TidiGameplayMessagingSubsystem.csAssets/GlobalMessages/— Message channel definitions
Manual GC control to prevent runtime stutters:
| Feature | Description |
|---|---|
| Disabled Auto-GC | Full manual control in production builds |
| Heap Threshold | Adaptive threshold based on system RAM |
| Stutter Detection | Monitors GC frequency, increases threshold on stutter |
| Scene Transition Cleanup | Full compacting GC on scene unload |
| Memory Profiling | Exposes GetMemoryUsage(), GetMonoHeapUsage() |
Key Files:
Assets/TidiGC/TidiGCManager.cs— Singleton GC manager
Unity New Input System with layered managers:
| Layer | Description |
|---|---|
| POIInputManager | Raw input reading (Punch, Pause) |
| POIInputCommandManager | Command-layer abstraction for gameplay |
| InputManager (base) | Generic input action handling |
Key Files:
Assets/PathOfTheInfected - Core/Scripts/Input/POIInputManager.csAssets/TidiMovementComponent2D/scripts/Misc/InputManager.cs
Generic object pooler for projectiles, particles, and prefabs:
ObjectPooler— Base pool manager with spawn/despawnTidiGenericObjectPooling— Runtime pooling for dynamic objects
Key Files:
Assets/TidiMovementComponent2D/scripts/Core/ObjectPooler.csAssets/TidiMovementComponent2D/scripts/TidiGenericObjectPooling/ObjectPoolManager.cs
| Category | Technology |
|---|---|
| Engine | Unity 6000.3.6f1 (Unity 6) |
| Language | C# (.NET) |
| Input | Unity New Input System |
| UI | Unity UI Toolkit (VisualElements) |
| Physics | Unity 2D Physics (BoxCollider2D, Rigidbody2D) |
| Animation | Unity Animator with Playables (TidiAnimationDriver) |
| Resolution | 1920x1080 (Linear color space) |
| Platform | Windows (Build Target 19) |
The project uses 11 custom .asmdef assemblies with clear dependency boundaries:
| Assembly | GUID | Description | Dependencies |
|---|---|---|---|
TidiSystems |
3b6257f84980fdc428a1d48db325deb5 |
Core 2D movement, animation, physics, states | — |
TidiGameplayMessaging |
75469ad4d38634e559705d17036d5f35 |
Typed event/message bus | — |
TidiPathFinding |
f5cdf24af6a043b897086d4de2582826 |
Enemy AI pathfinding | — |
TidiPatjFindingEditor |
— | Editor tooling for pathfinding | TidiPathFinding |
TidiGC |
— | Garbage collection management | — |
TidiModularUISystem |
— | Component-based UI framework | — |
ClothSystem |
— | Verlet cloth simulation | TidiSystems |
GlobalMessages |
— | Message channel definitions | TidiGameplayMessaging |
PathOfTheInfected - Core |
— | Game-specific mechanics and behaviors | All above |
PathOfTheInfected - Gameplay |
— | Gameplay managers and systems | Core assemblies |
PathOfTheInfected - UI |
— | UI implementation | TidiModularUISystem |
PathOfTheInfected/
├── Assets/
│ ├── TidiMovementComponent2D/ # Reusable 2D controller framework
│ │ ├── scripts/
│ │ │ ├── Core/ # PlayerSM singleton, state machine
│ │ │ ├── States/ # ~16 player states
│ │ │ ├── Physics/ # MovementController, collision
│ │ │ ├── Animation/ # AnimInstance, BlendSpaces, Playables
│ │ │ ├── Cloth/ # Verlet cloth simulation
│ │ │ ├── Misc/ # GhostTrail, InputManager, Pooling
│ │ │ └── Tweening/ # TidiTween
│ │ └── TidiSystems.asmdef
│ │
│ ├── TidiGameplayMessaging/ # Typed event bus
│ │ ├── Core/ # Messaging subsystem
│ │ └── TidiGameplayMessaging.asmdef
│ │
│ ├── TidiPathFinding/ # Enemy navigation
│ │ ├── Core/ # Pathfinding engine
│ │ ├── Editor/ # Editor tools
│ │ └── TidiPathFinding.asmdef
│ │
│ ├── TidiGC/ # GC management
│ │ ├── TidiGCManager.cs
│ │ └── TidiGC.asmdef
│ │
│ ├── TidiModularUISystem/ # UI Toolkit framework
│ │ ├── Scripts/Core/
│ │ │ ├── Screens/ # UIScreen controllers
│ │ │ ├── Views/ # UIView components
│ │ │ ├── Routers/ # UIRouter lifecycle
│ │ │ └── Components/ # UIComponent decorators
│ │ └── TidiModularUISystem.asmdef
│ │
│ ├── GlobalMessages/ # Message channel definitions
│ │ └── GlobalMessages.asmdef
│ │
│ └── PathOfTheInfected - Core/ # Game-specific code
│ ├── Scripts/
│ │ ├── Player/
│ │ │ ├── Combat/ # PlayerCombat, attacks, subsystems
│ │ │ └── Health/ # PlayerHealth
│ │ ├── Combat/
│ │ │ ├── Attack Definition/ # ScriptableObject attacks
│ │ │ ├── Subsystems/ # RBC, Combo, Perks
│ │ │ └── HitDispatcher.cs # Damage routing
│ │ ├── Enemy/
│ │ │ ├── Enemy brains/ # AI decision making
│ │ │ ├── States/ # Enemy state machines
│ │ │ ├── Attack/ # Melee, ranged, touch attacks
│ │ │ ├── Health/ # EnemyHealth
│ │ │ ├── Projectiles/ # Projectile base
│ │ │ └── Interfaces/ # ISpottable, IEnemyMoveable
│ │ ├── Boss/
│ │ │ ├── Brains/ # BossBrain
│ │ │ ├── Phases/ # BossPhase transitions
│ │ │ └── States/ # Boss combat states
│ │ ├── Animation/
│ │ │ ├── POIAnimInstance.cs # Game-specific anim controller
│ │ │ ├── States/ # Standing, InAir states
│ │ │ └── BlendSpaces/ # 1D/2D blend trees
│ │ ├── Input/ # POIInputManager, command layer
│ │ ├── Damagable/ # Health, hit response
│ │ └── Spottable/ # PlayerSpot marker
│ ├── Prefabs/
│ │ ├── Enemy/ # FlyingPuncher, MeleePuncher
│ │ ├── Projectiles/ # Projectile prefabs
│ │ └── Player/ # Player prefab
│ ├── Scenes/
│ │ └── SampleScene.unity # Main game scene
│ └── PathOfTheInfected.asmdef
│
├── PathOfTheInfected - Gameplay/ # Gameplay managers
│ └── PathOfTheInfected - Gameplay.asmdef
│
└── PathOfTheInfected - UI/ # UI implementation
├── Scripts/
│ ├── Router/ # POIRouter
│ └── PlayerUI/ # HealthBar, screens
└── PathOfTheInfected - UI.asmdef
| Pattern | Usage |
|---|---|
| Singleton | PlayerSm.Instance, POIAnimInstance.Instance, TidiGameplayMessagingSubsystem.Instance, TidiGCManager |
| State Machine | Player movement (~16 states), Enemy AI (3-state), Animation (Standing/InAir), Boss phases |
| SubSystem Pattern | Combat subsystems (RBC, Combo, Perks) registered and updated centrally |
| Observer Pattern | Gameplay messaging (pub/sub), animation events (OnAnimationEnded) |
| Command Pattern | Input abstraction layer (POIInputCommandManager) |
| Strategy Pattern | Attack definitions as ScriptableObjects (PlayerAttackSoBase) |
| Object Pooling | Projectiles, particles, prefabs |
| Component Pattern | Modular UI (UIComponent, ControllerIconDecorator) |
| BitFlags | CombatIntentFlags, CombatFlags for packed state storage |
ScriptableObjects are used for:
- Attack Definitions — Damage, range, startup/active/recovery times
- Enemy Stats — HP, speed, aggro range
- State Definitions — Enemy states as SO assets (
EnemyWanderSO,EnemyAggroSO) - Perk Data — Passive bonuses (
PlayerPerkData) - Obsolete (perks were removed late in development but the data structure remains)
This project was developed as part of a Game Development class. It demonstrates:
- State machine architecture for movement, animation, and AI
- Physics-based character effects (Verlet cloth/scarf simulation)
- Combat systems with combo tracking, damage multipliers, and perk integration
- Decoupled architecture using a typed messaging bus
- Enemy AI with spotting, pursuit, and attack behaviors
- Boss battles with phase transitions
- Garbage collection management for consistent performance
- Modular UI framework built on Unity UI Toolkit
- Reusable component libraries designed for cross-project use
- Unity 6000.3.6f1 (Unity 6) or compatible 2022.x version
- Windows build support
- New Input System package (enabled in Project Settings)
- Clone or download this repository
- Open Unity Hub → Add → Select the
PathOfTheInfectedfolder - Wait for package restoration and assembly compilation
- Open
Assets/PathOfTheInfected - Gameplay/Levels/MainMenu.unity - Press Play in the Unity Editor
| Action | Input |
|---|---|
| Move | WASD or Arrow Keys |
| Jump | Space or Z |
| Dash | C |
| Punch | X |
| Return To Main Menu | Escape |
| Action | Input |
|---|---|
| Move | DPAD or Left Stick |
| Jump | A |
| Dash | RT |
| Punch | X |
| Return To Main Menu | ☰ |
- branching: Feature branches follow
Feat_<FeatureName>convention- Example:
Feat_ModularUIFramework,Feat_ExtendingAttacksAndWeaponSystem
- Example:
- Main branch:
main - Development environment: Unity Editor (no CLI build scripts)
| File | Purpose |
|---|---|
README.md |
This file — feature list, tech stack, project structure |
Built with Unity by a high school Game Development student - Harel Tidhar 🎮