Spawning
Spawning a Networked Actor
Fusion piggybacks on Unreal's normal actor spawn flow. There is no FusionSpawnActor API, no networked counterpart to UWorld::SpawnActor. Spawn the actor with the standard SpawnActor family of calls, and Fusion adopts it as networked through a UFusionActorComponent on the actor.
This is the spawn equivalent of the shared-authority shift introduced in Concepts. Built-in Unreal replication requires the spawn to originate on the authoritative server, which then replicates the spawn to clients. Fusion has no authoritative server, so the spawning client itself owns the new actor; the room replicates the actor's existence to other clients through a handshake on the UFusionActorComponent.
C++
// In the actor's constructor:
FusionActorComponent = CreateDefaultSubobject<UFusionActorComponent>(TEXT("Fusion"));
SetReplicates(true);
// Anywhere in gameplay code:
AMyNetActor* Spawned = GetWorld()->SpawnActor<AMyNetActor>(
AMyNetActor::StaticClass(), SpawnLocation, SpawnRotation);
Adding the Fusion Actor Component
The UFusionActorComponent is the bridge between an actor and UFusionClient. Add one to any actor blueprint or C++ class that should be networked. Without the component, the actor is local-only — even if bReplicates is set, Fusion does not adopt it, because Fusion replication is opt-in via the component, not via the stock UE replicates flag (see Compatibility with Built-in Netcode).
The Ownership property on the component picks the ownership mode for the actor — Transaction, PlayerAttached, Dynamic, MasterClient, or GameGlobal. The mode controls who can take ownership at runtime and what happens to the actor when its owner disconnects. The full mode-by-mode treatment is in Ownership.
Map-Placed Replicated Actors
Actors dropped directly into a level — placed in the editor and saved with the map — are networked through a different path than runtime-spawned actors. UFusionOnlineSubsystem::AttachCurrentMap() walks the loaded level after the session is in a room and registers every actor that has a UFusionActorComponent. No runtime spawn happens; the existing instance becomes the networked one.
The component handles its own attachment by default. In BeginPlay it calls AddActorSource() automatically, unless bSkipAutoAttach is set to true on the component. Set that flag when registration needs to be deferred — for example, when the actor must complete a custom asynchronous setup before becoming networked — and call UFusionOnlineSubsystem::AttachActor(Actor) later when the actor is ready.
The Quick Start Guide walks through a setup-actor placement pattern: a small actor dropped in the level that connects to Photon on BeginPlay, then calls AttachCurrentMap once OnConnectedToPhoton fires. Reuse the pattern in production projects — the asset name in the quick-start is for illustration only.
Persistent vs Dynamic Actors
Map-placed actors persist for the lifetime of the loaded level. They never disappear because of an ownership transfer or a player disconnect — only because of a map change or an explicit destroy. Runtime-spawned actors are governed by their ownership mode and live until explicitly destroyed or, depending on EFusionObjectOwnerFlags, until their owner leaves the room.
| Map-placed (persistent) | Runtime-spawned (dynamic) | |
|---|---|---|
| Origin | Placed in the editor, saved with the map | SpawnActor at runtime |
| How late-joiners see it | Already present in the level when they load the map | Re-spawned by the room from the replicated state |
| Lifetime | Lives until the level unloads | Lives until destroyed or owner leaves (per ownership mode) |
| Typical ownership modes | MasterClient, GameGlobal |
PlayerAttached, Transaction, Dynamic |
The lifetime side-effects of each ownership mode — what happens on disconnect, on master migration, on SetWantsOwner — are detailed in Ownership.
Lifetime and Destruction
Destruction is reported through UFusionActorComponent::OnObjectDestroyed, a BlueprintAssignable multicast. The event carries an EFusionObjectDestroyMode reason, so handlers can react differently to gameplay-driven destroys, map changes, and shutdown.
| Reason | Fires when |
|---|---|
Local |
The local client destroyed the actor. |
Remote |
The actor's owner destroyed it on a remote peer; the destroy was replicated in. |
MapChange |
The current map is being unloaded as part of a ChangeWorld. |
Shutdown |
The Fusion session is being torn down — leaving the room or disconnecting. |
RejectedNotOwner |
The local client attempted to destroy an actor it does not own; the destroy was rejected. |
ForceDestroy |
Plugin-driven forced destroy, used during error recovery and edge-case cleanup. |
C++
void AMyActor::HandleDestroyed(EFusionObjectDestroyMode Reason)
{
switch (Reason)
{
case EFusionObjectDestroyMode::MapChange:
case EFusionObjectDestroyMode::Shutdown:
return; // Ignore framework-driven destroys.
default:
ReleaseGameplayResources();
break;
}
}
Gate cleanup logic on the reason. Ignore MapChange and Shutdown when the handler only cares about gameplay-driven despawns (otherwise the cleanup runs once when the player dies and again when they leave the match). Treat RejectedNotOwner as a programming error: it means the local code tried to destroy a remote-owned actor.
Spawning from C++ vs Blueprints
Both paths share the same UFusionActorComponent. The difference is only where the component is added: in the C++ constructor for native classes, or via the Blueprint editor's Add Component menu for blueprints.
C++
AMyNetActor::AMyNetActor()
{
FusionActorComponent = CreateDefaultSubobject<UFusionActorComponent>(TEXT("Fusion"));
FusionActorComponent->Ownership = EFusionObjectOwnerFlags::PlayerAttached;
SetReplicates(true);
}
The Blueprint-callable spawning surface lives on UFusionOnlineSubsystem (AttachActor, AttachCurrentMap) and on the static helpers in UFusionHelpers such as AddActorComponent and DestroyActorComponent. The helpers let Blueprint code add or remove a UFusionActorComponent at runtime without touching the actor class.
Prefer Blueprints for fast iteration on actor templates. Drop to C++ when the actor needs to override ShouldAddComponentType, configure FusionObjectFlags before BeginPlay, or set up bSkipAutoAttach for deferred registration.
Ready Events
OnObjectReady on UFusionActorComponent fires once the actor has completed its networked handshake. From that point the replicated state on the actor is safe to read and write. Bind to this event instead of BeginPlay for network-dependent initialization — BeginPlay runs before the Fusion handshake is finished, so replicated values read there may be defaulted.
UFusionOnlineSubsystem::OnObjectReady is the subsystem-wide equivalent. It fires for every Fusion-networked object as that object becomes ready, with the actor passed as a parameter. Use it for systems that observe every newly ready object — a debug HUD, a global registry — without holding a per-actor binding.
C++
void AMyActor::BeginPlay()
{
Super::BeginPlay();
FusionActorComponent->OnObjectReady.AddDynamic(this, &AMyActor::HandleReady);
FusionActorComponent->OnObjectDestroyed.AddDynamic(this, &AMyActor::HandleDestroyed);
}
Back to top