Photon Fusion Integration Guide

The Runtime Spawner package (from version 1.5.0 and higher) includes optional integrations for Photon Fusion 2.x, enabling fully networked spawning, pooling, and synchronization.

This guide explains how to set up your project, assemblies, and bootstrap flow to use the spawner with Fusion’s NetworkRunner.


Overview

Runtime Spawner can operate seamlessly inside a Fusion session:

  • The host or server instance performs all spawn logic.

  • Clients automatically observe replicated objects through Fusion’s built-in network synchronization.

Key benefits:

  • Authoritative spawning managed by the host.

  • Full pooling support via:

    • FusionPoolProvider (core INetworkObjectProvider passed into StartGameArgs.ObjectProvider), or

    • FusionPoolObjectProviderBehaviour (MonoBehaviour attached to the NetworkRunner GameObject).

  • Lifecycle synchronization for AI, players, and encounter systems.

  • Drop-in integration using FusionFactoryAsset and FusionObjectFactory.

Using the Runtime Spawner Fusion Pool Provider

The Runtime Spawner provides an Pooling system that directly integrates with Fusion, providing automatic pooling and object lifecycle management for your Fusion-based games.

Please refer to this page in the manual for more information:

Using the Runtime Spawner Fusion Pool Provider


1. Assembly Definition Requirements

Any assembly definition (asmdef) that contains Fusion-related scripts (such as FusionBootstrap, CharacterController_Fusion, or your own NetworkBehaviour components) must be processed by Fusion’s CodeGen (Weaver) system.

Required Configuration

Setting
Required Value

Assembly references

Fusion.Unity, Unity.Fusion.CodeGen

Define constraint

FUSION_WEAVER

Recommended reference

RuntimeSpawner.Integrations.Fusion

Tip: The FUSION_WEAVER define ensures your scripts are compiled with Fusion’s code generation pipeline.


2. Add Assemblies to the CodeGen List

  1. Go to Tools → Fusion → Network Project Config

  2. Add all assemblies that contain networked behaviours to Assemblies to Process, including:

    • RuntimeSpawner.Integrations.Fusion

    • RuntimeSpawner.Fusion.Samples

    • Your own gameplay assemblies containing NetworkBehaviour classes

If you skip this step, Fusion will log: NetworkObjectSpawnException: Failed to spawn: behaviour not weaved


3. Run the Fusion Code Generator

After updating assemblies or define constraints:

  1. In the Unity menu bar, select Fusion → CodeGen → Run CodeGen

  2. Wait for a console message like: Fusion CodeGen: processed N behaviours in <AssemblyName>

Once complete, all networked prefabs (players, AI, etc.) will be valid for runtime spawning via the FusionObjectFactory and FusionPoolObjectProvider.


4. Bootstrap Flow Overview

The Fusion Bootstrap Sample (included in the packages Fusion sample) demonstrates a complete setup:

  1. Player clicks Start in the UI.

  2. A NetworkRunner is created (or re-used) and configured with a pooling INetworkObjectProvider:

    • In the sample, this is new FusionPoolProvider(new PoolAdapter()) passed into StartGameArgs.ObjectProvider.

  3. The host (or peer 0 in Shared mode) spawns player prefabs for each joining client.

  4. When the local player spawns, the bootstrap binds the camera.

  5. Once the host player exists, the bootstrap triggers:

    spawner.Init();
    spawner.StartSpawners();

    to begin population and encounters.

Key Rules

  • Only the Host/Server runs the RuntimeSpawner.

    • Clients observe replicated results automatically.

  • Player prefabs must include a NetworkObject component and be registered in Project Settings → Fusion → Network Prefabs.

  • In Shared Mode, both players and AI synchronize automatically without a dedicated server.


5. Quick Setup Checklist

Setting / Asset
Required Value

Assembly references

Fusion.Unity, Unity.Fusion.CodeGen

Define constraints

FUSION_WEAVER

CodeGen assemblies

Include all with NetworkBehaviour scripts

Network Prefab Table

Register all player, AI, and pooled prefabs

Runner Object Provider

FusionPoolObjectProvider

Spawner Factory

FusionFactoryAsset

Host Init Flow

spawner.Init() → spawner.StartSpawners() after player spawn


6. Common Errors and Fixes

Error
Likely Cause
Fix

FailedToCreateInstance (prefab: [Name])

Prefab missing from Network Prefab Table

Add prefab under Project Settings → Fusion → Network Prefabs

NetworkObject not weaved

Assembly not processed by CodeGen

Add the asmdef to Fusion CodeGen and re-run

INetworkObjectProvider returned null

Provider not assigned or pool not initialized

Ensure provider is set in StartGameArgs.ObjectProvider and prefabs have NetworkObject

Nothing spawns in multiplayer

RuntimeSpawner never started on host

Confirm bootstrap calls spawner.Init() and StartSpawners() after host player spawn

Prefabs spawn locally but not on remote

Prefab not in Network Prefab list

Register prefab in Project Settings

Errors mentioning “behaviour not weaved”

Assembly not processed by CodeGen

Add asmdef to CodeGen list and re-run


7. Tips for Custom Projects

  • For small projects or tests, put all Fusion scripts in a single asmdef (e.g. RuntimeSpawner.Fusion.Samples) and include it in CodeGen - simplest setup.

  • Use Fusion’s Simulation Info HUD to confirm authority and observe replication during play.

  • When testing locally:

    • Run one instance as Host.

    • Run a second instance as Client.

    • Verify that both players spawn and the host begins spawner-driven population.

You can use the Parrel Sync Package to load and test multiple Untiy Editor instances easily


8. Advanced Integration Notes

Lifecycle Coordination

SpawnDirector and SpecialEncounterManager support:

  • Pause() – temporarily halts spawning during match transitions or network pauses.

  • Resume() – continues spawn flow without reinitialization.

  • End() – clean teardown for disconnects or scene transitions.

These lifecycle calls work cleanly alongside Fusion’s object pool and replication logic.

Pooling Bridge

The Fusion pool providers connect the Runtime Spawner’s pool system directly to Fusion’s runner:

  • FusionPoolProvider – a core INetworkObjectProvider you construct in your bootstrap and pass to StartGameArgs.ObjectProvider.

  • FusionPoolObjectProviderBehaviour – a MonoBehaviour INetworkObjectProvider that you attach to the same GameObject as your NetworkRunner.

When a pooled object is spawned by the host, it’s automatically replicated to all connected peers. Despawns and returns to the pool are mirrored network-wide.

FusionObjectFactory.Prewarm recognizes both providers and forwards Prewarm(GameObject, int) calls accordingly.


9. Example: Integrating with Your Own Custom Bootstrap

If you already have custom Fusion startup logic (your own Bootstrap, GameManager, etc.), you don’t need to use the sample bootstrap. You only need to:

  1. Ensure your NetworkRunner is started with an appropriate object provider:

    • FusionPoolProvider or

    • FusionPoolObjectProviderBehaviour

  2. Use a FusionFactoryAsset (or FusionObjectFactory constructed in code) to plug the spawner into your runner.

  3. Call spawner.Init() and spawner.StartSpawners() on the authoritative side once the host/local player is ready.

Option A – Core Provider (FusionPoolProvider)

This is closest to the sample:

using Fusion;
using UnityEngine;
using MegaCrush.Spawner;
using MegaCrush.Spawner.FusionAdapter;

public class MyFusionBootstrap : MonoBehaviour
{
    [SerializeField] private NetworkRunner runnerPrefab;
    [SerializeField] private RuntimeSpawner spawner;

    private NetworkRunner _runner;

    private async void Start()
    {
        _runner = Instantiate(runnerPrefab);

        // Bridge Fusion to your Runtime Spawner pool via PoolAdapter.
        var provider = new FusionPoolProvider(new PoolAdapter())
        {
            DelayIfSceneManagerIsBusy = true
        };

        var args = new StartGameArgs
        {
            GameMode       = GameMode.Host,
            SessionName    = "MySession",
            ObjectProvider = provider,
            // SceneManager = your INetworkSceneManager, if any
        };

        var result = await _runner.StartGame(args);
        if (!result.Ok)
        {
            Debug.LogError($"Fusion start failed: {result.ShutdownReason}");
            return;
        }

        if (_runner.IsServer)
        {
            spawner.Init();
            spawner.StartSpawners();
        }
    }
}

Option B – Behaviour-based Provider (FusionPoolObjectProviderBehaviour)

If your project already expects providers as components on the runner (e.g. your own NetworkObjectProviderDefault subclass):

using Fusion;
using UnityEngine;
using MegaCrush.Spawner;
using MegaCrush.Spawner.FusionAdapter;

public class MyFusionBootstrap : MonoBehaviour
{
    [SerializeField] private NetworkRunner runnerPrefab;
    [SerializeField] private RuntimeSpawner spawner;

    private NetworkRunner _runner;

    private async void Start()
    {
        _runner = Instantiate(runnerPrefab);

        // Attach the behaviour-based provider to the runner GameObject.
        var provider = _runner.GetComponent<FusionPoolObjectProviderBehaviour>();
        if (provider == null)
            provider = _runner.gameObject.AddComponent<FusionPoolObjectProviderBehaviour>();

        var args = new StartGameArgs
        {
            GameMode       = GameMode.Host,
            SessionName    = "MySession",
            ObjectProvider = provider,
            // SceneManager = your INetworkSceneManager, if any
        };

        var result = await _runner.StartGame(args);
        if (!result.Ok)
        {
            Debug.LogError($"Fusion start failed: {result.ShutdownReason}");
            return;
        }

        if (_runner.IsServer)
        {
            spawner.Init();
            spawner.StartSpawners();
        }
    }
}

In both cases, FusionFactoryAsset (if you’re using it) will:

  • Find the active NetworkRunner.

  • Use its ObjectProvider (either FusionPoolProvider or FusionPoolObjectProviderBehaviour).

  • Provide a FusionObjectFactory that the RuntimeSpawner will use for networked spawning.


10. Troubleshooting Summary

Symptom
Check
Resolution

Host works, clients see nothing

Spawner running on host only

Guard spawn logic with if (runner.IsServer) and ensure spawner.StartSpawners() is called on host

Pool not returning objects

Object provider setup

Verify FusionPoolProvider / FusionPoolObjectProviderBehaviour is assigned to ObjectProvider

Prefabs spawn locally but not on remote

Network Prefab registration

Register prefabs in Project Settings → Fusion → Network Prefabs

Errors mentioning “behaviour not weaved”

CodeGen configuration

Add assemblies to Fusion CodeGen list and re-run

INetworkObjectProvider never hit

Wrong provider or not passed to StartGameArgs

Ensure ObjectProvider is set on StartGameArgs before calling StartGame


✅ You’re Ready to Go

Once your assemblies are weaved, prefabs registered, and your NetworkRunner started with either FusionPoolProvider or FusionPoolObjectProviderBehaviour (plus a FusionFactoryAsset or FusionObjectFactory in play), the Runtime Spawner will automatically handle networked spawning, despawning, and pooling across host and clients.

Use the provided Fusion Bootstrap Sample scene as a reference template, then adapt the integration snippets above to match your own custom Fusion startup logic.

Also see:

Last updated