Skip to content

Architecture Overview

This document describes the high-level architecture of the Monsta Choppa VR project. The system is built on Unity's XR Interaction Toolkit with custom layers for gameplay, data management, and UI.

Source: Assets/Scripts/


Core Design Principles

Principle Implementation
Decoupled Systems Event channels for communication, no direct references
Data-Driven Design ScriptableObjects define all game content
VR Performance Object pooling, priority updates, minimal allocations
Extensibility Generic base classes, factory patterns

System Layers

flowchart TB
    subgraph Presentation["Presentation Layer"]
        A1[UI Hosts]
        A2[Views]
        A3[Audio]
        A4[Visual Effects]
    end

    subgraph Gameplay["Gameplay Layer"]
        B1[Weapons]
        B2[Enemies]
        B3[Combat]
        B4[Arena Management]
    end

    subgraph Events["Event Layer"]
        C1[GameplayEvents]
        C2[AudioEvents]
        C3[SystemEvents]
    end

    subgraph Data["Data Layer"]
        D1[ScriptableObject Databases]
        D2[Object Pooling]
        D3[Constants]
    end

    subgraph VR["VR Template Layer"]
        E1[XR Origin]
        E2[Controllers]
        E3[Locomotion]
    end

    Presentation --> Gameplay
    Gameplay --> Events
    Events --> Data
    Data --> VR

Data-Driven ScriptableObject Pattern

The project uses a consistent pattern where ScriptableObjects define configuration and MonoBehaviours handle runtime logic.

Pattern Flow

flowchart LR
    A[ScriptableObject Data] --> B[MonoBehaviour Controller]
    B --> C[Components]

    A1[WeaponData] --> B1[XRWeaponBase]
    A2[EnemyData] --> B2[EnemyController]

Benefits

Benefit Explanation
Designer-friendly Configure in Inspector without code changes
Runtime immutable Data assets are read-only, no accidental modifications
Easy balancing Tweak stats by editing assets, not code
Pooling compatible Same data drives multiple pooled instances

Key System Relationships

Weapon System

graph TD
    A[WeaponData] --> B[WeaponDatabase]
    A --> C[XRWeaponBase]
    C --> D[MeleeXRWeapon]
    C --> E[ShieldXRWeapon]
    C --> F[BowXRWeapon]
    D --> G[WeaponHitbox]

Enemy System

graph TD
    A[EnemyData] --> B[EnemyDatabase]
    A --> C[EnemyController]
    C --> D[EnemyHealth]
    C --> E[EnemyMovement]
    C --> F[EnemyAnimator]
    C --> G[EnemyAttack]

Object Pooling

Source: GamePoolManager.cs

graph TD
    A[GamePoolManager] --> B[Enemy Pools]
    A --> C[Particle Pools]
    A --> D[WorldAudio Pools]
    B --> E[keyed by EnemyData]
    C --> F[keyed by ParticleData]
    D --> G[keyed by WorldAudioData]

Usage:

// Spawn
var enemy = GamePoolManager.Instance.GetEnemyPrefab(enemyData, position, rotation);

// Return
GamePoolManager.Instance.ReturnEnemyPrefab(enemyController);


Static Access Layer

Global access to databases and events through static classes:

// GameDatabases - centralized database access
GameDatabases.WeaponDatabase.TryGet("sword_fire", out var weapon);
GameDatabases.EnemyDatabase.Get("goblin_melee");

// Event Registries - centralized event access
GameplayEvents.GoldChanged.Raise(newGold);
GameplayEvents.EnemySpawned.Subscribe(HandleEnemySpawn);
AudioEvents.SfxRequested.Raise("hit_sound");

Best Practices

Rule Reason
Always unsubscribe in OnDisable Prevents memory leaks and null references
Never modify ScriptableObjects at runtime Breaks data consistency
Use TryGet for database lookups Handles missing entries gracefully
Pool all instantiated objects Avoids GC spikes in VR
Keep Update logic minimal VR requires consistent 72+ FPS

File Organization

Assets/Scripts/
├── Attributes/            # FloatAttribute, IntAttribute
├── Audio/                 # Audio controllers
├── Characters/            # Base and Enemy components
│   ├── Base/             # HealthComponent, AnimatorComponent
│   └── Enemies/          # EnemyController, EnemyHealth, etc.
├── Constants/            # GameConstants, AudioKeys, etc.
├── Data/                 # ScriptableObject data classes
│   ├── Core/             # EnemyData, ParticleData
│   ├── Progression/      # MetaProgressionData
│   └── Weapons/          # WeaponData, WeaponModifierData
├── Databases/            # DatabaseBase<T>, GameDatabases
├── Events/               # Event channels and registries
│   ├── Channels/         # EventChannel<T>
│   └── Registries/       # GameplayEvents, AudioEvents
├── Factories/            # UIToolkitFactory
├── Interfaces/           # IDamageable, IUpdateable
├── Pooling/              # GamePoolManager
├── Saves/                # SaveFileManagerBase
├── Systems/              # Arena, Hub systems
│   └── Arena/            # WaveSpawner, EnemyManager
├── UI/                   # Views, Hosts, Controllers
│   ├── Views/            # BasePanelView
│   └── Hosts/            # BasePanelHost
└── Weapons/              # Weapon components