This document is about: FUSION 2
SWITCH TO

This page is a work in progress and could be pending updates.

Project Architecture

The Unity Project

The project follows a standard Unity project structure. All scenes are located in the Scenes folder, with Game being the main scene. Unlike typical games, the Fusion MMO sample does not have a separate menu scene - instead, it features a compact connection menu directly within the Game scene. All scripts in the Scripts folder are thoroughly commented to help you understand the codebase.

High Level Breakdown

The game starts from the UIGameMenu script, which calls the Connect method on the ConnectionManager script. The ConnectionManager handles both the initial connection and transfer logic when a player moves to a different game session through a Remote Portal (see Player Transfer for more details).

In Shared Mode, each player typically handles their own spawn logic, and Fusion MMO follows this pattern. The GameManager script manages player spawning, while the EnemySpawner script handles enemy spawning. Enemy AI is controlled by nearby players (see Enemies for more details).

The Player and Enemy scripts inherit from a base class called Agent, which contains shared properties and functionality. The Agent script also manages sensors - components that periodically gather information about the game world for their owner (the agent). Examples include the AreaSensor, FindTargetSensor, and LineOfSightSensor.

This project uses two key addons for both enemies and players:

The Health component tracks agent health points. To provide responsive feedback during combat, the health component can predict health changes even before the player gains authority over the target object.

Players

The Player script manages all essential player functionality including movement, finite state machine (FSM) updates, input handling, abilities, camera control, and character progression.

Players use a finite state machine to control their behavior. The FSM states determine how the player moves, which animations play, which abilities can be used, and which effects (sounds, particles) are triggered. The main player state is LocomotionState.

The game features three player abilities, each implemented as a distinct FSM state that the player can transition into:

  • MeleeAbility - A melee attack state that deals damage to nearby enemies
  • DashAbility - A dash state that provides quick mobility and temporary invulnerability
  • SpawnEffectAbility - A spawn effect state that allows precise placement of area effects using a top-down targeting system

Player Abilities

Players can earn experience points (XP) through a progression system by defeating enemies. When players accumulate enough XP to level up, they receive a full health restore and celebratory visual effects mark their achievement. A coin collection system is also included, though this serves as a demonstration feature only - there is no way to spend the coins in the sample.

The camera system provides smooth follow behavior with configurable zoom and rotation speeds.

Upon death, players respawn in the town area after a brief delay. The respawn system ensures players can quickly get back into the action without excessive downtime.

For testing purposes, players can be controlled by a basic AI system. For more details, see the Player AI section.

Enemies

Fusion MMO features three distinct enemy types:

  1. Dummy enemies (DummyEnemy script) are passive creatures that simply wander around and graze on grass.
  2. Melee enemies (MeleeEnemy script) actively patrol their spawn points and engage players with close-range attacks when they detect them.
  3. Ranged enemies (RangedEnemy script) patrol their territory and attack players from a distance using projectiles.

All enemies inherit from an Enemy base class which provides common functionality.

The EnemySpawner script manages enemy population in the game world. It dynamically adjusts spawn counts based on spawner settings and the number of players in an area. As more players enter an area, the spawner increases the enemy count to maintain engaging gameplay. Enemy spawners are controlled by the master client.

Enemy AI, animations, and visual effects are driven by states from the Fusion FSM addon. All enemy states can be found in the Scripts/States/Enemy States folder. To ensure correct execution order (Sensors Update -> State Changes -> FSM Update -> Movement), the FSM is updated manually from the FixedUpdateNetwork method in the Enemy script.

Enemies use multiple sensors to gather information about their environment:

  • FindTargetSensor identifies the best target from visible players
  • AreaSensor tracks which area the enemy currently occupies
  • LineOfSightSensor (used by ranged enemies) verifies clear shooting paths to targets

For pathfinding, the game utilizes Unity's AI Navigation package. The NavMeshSurface component is attached to the Environment game object in the Game scene.

Distributed Enemy Authority

Since there is no dedicated server in Shared Mode to run enemy AI, and a single client (master client) would be overwhelmed trying to calculate AI for all enemies, the game distributes AI calculations among the closest players. This approach allows the enemy count to scale efficiently as more players join.

Enemy Authority

The system works in a straightforward way: As a player moves through the environment, their AIControlSensor script periodically scans for nearby enemies that aren't currently controlled by any player (those without assigned state authority). When such an enemy is detected, the player requests authority over it. The player will also release authority over any enemies that is too far away. This entire functionality is implemented in the AIControlSensor script.

Interactables

The game includes a flexible interaction system that enables players to interact with various objects in the world, such as opening chests, picking up items, and using portals. The InteractionSensor component continuously scans for nearby interactable objects within its detection radius.

For an object to be interactable, it must meet two requirements:

  1. Have a Collider component set to the Interactable layer
  2. Contain a script that implements the IInteractable interface

The IInteractable interface defines two key methods:

  • CanInteract() - Determines if interaction is currently possible
  • Interact() - Executes the interaction logic when triggered

Common interactable objects include:

  • Chests that can be opened to receive coins and health boost
  • Portals for traveling between different locations
  • Pickups that provide instant benefits when collected:
    • Health pickups restore a portion of player health
    • Coin pickups add to the player's currency

The chest prefab (Assets/Prefabs/Interactables/Chest) provides a good example implementation, showing how to properly set up collision detection and handle networked interaction events.

Chest Opening

Portals

Portals are special interactable objects that allow players to teleport between different locations in the game world. The game features two distinct types of portals:

LocalPortal enables teleportation between two points within the same scene. When a player interacts with a local portal, it activates the Portal State on the player's state machine, which creates a smooth transition by playing spinning animations and visual effects before teleporting the player to the destination point. Local portals work in pairs - each portal has a designated target portal that players will be teleported to.

Local Portal

RemotePortal facilitates travel between different game scenes and sessions. When used, it initiates a Player Transfer process that preserves the player's progress and state while moving them to a new scene and game session. Each remote portal has a unique identifier and maintains information about its target scene and destination portal. To ensure consistent multiplayer experiences, remote portals track the most recent session name used for teleportation, so all players teleport to the same session.

Player Transfer

The game implements a seamless player transfer system that allows players to move between different scenes and game sessions while preserving their progress and state. This functionality is primarily used by Remote Portals to enable travel between different game areas.

When a player interacts with a Remote Portal, it initiates the transfer process by:

  1. Creating a TransferData object containing:

    • Origin session name and scene
    • Target session name, scene, and portal ID
    • Player state data (level, XP, health, coins, ability cooldowns)
  2. The ConnectionManager handles the actual transfer by:

    • Disconnecting from the current session
    • Connecting to the target session
    • Loading the new scene
    • Showing/hiding loading UI during the process
  3. In the new session, the GameManager:

    • Locates the destination portal using the portal ID
    • Spawns the player at the portal location
    • Restores the player's state from the transfer data

Remote Portal

Additionally, the PhotonAppSettings' EmptyRoomTTL setting keeps sessions alive for a short period even when empty, ensuring players can successfully transfer back to their original session.

Areas

Areas are defined regions in the game world that help manage gameplay mechanics and difficulty scaling. Each area is defined by one or more bounds and can contain enemy spawners. The Area class tracks important information like:

  • Area name and ID
  • Current player count in the area
  • Whether sprinting is allowed
  • Area level (scales with player count)

The AreaManager maintains a list of all areas in the scene and tracks player distribution across them. It updates player counts per area every second, which affects enemy spawning and difficulty.

Players and enemies use an AreaSensor component to detect which area they are currently in. The sensor checks the player's position against area bounds. Players receive notifications when entering new areas.

Areas

Difficulty Scaling

The game features dynamic difficulty scaling based on player count in each area:

Area Level:

  • Base level increases with number of players in the area
  • Affects overall enemy strength in that area

Enemy Count:

  • Each spawner maintains a base number of enemies
  • Additional enemies spawn based on player count
  • Maximum enemies per spawner is capped

Enemy Scaling:

  • Enemies dynamically adjust their level based on number of players in their area
  • Level adjustments happen silently in the background when enemies are not in combat
  • Higher levels increase enemy health and damage
  • Ensures appropriate challenge as player count changes

This system automatically balances difficulty whether players are solo or in groups.

Scene Context

The SceneContext provides centralized access to scene-specific references like GameManager and AreaManager. Instead of inheriting directly from NetworkBehaviour, components can inherit from ContextBehaviour to automatically gain access to these scene-wide references through a cached Context property. This eliminates the need for manual reference lookups and provides a clean way to access scene managers from any networked object.

Back to top