This document is about: FUSION 2
SWITCH TO

Architecture - Client Host

Unity Project

All scripts live next to the assets of their example in the Assets folder.

Folder Content
/00_MainMenu Main menu scene, UIMainMenu script and the MenuButton prefab
/01_ThirdPersonCharacter Third Person Character scene, GameManager, Player and PlayerInput scripts and the Player prefab
/02_Platformer Platformer scene, Prefabs with Player, Coin, FallingPlatform, Flag and Cloud, Scripts with the example code
/03_Shooter Shooter scene, Prefabs with Player, Chicken and Impact, Scripts with the example code
/Common Runner and UIGameMenu prefabs, the InputSystem_Actions asset, Graphics and Scripts shared by all examples
/<Example>/3rdParty Third party assets, see Overview
/Photon Fusion SDK

The Simple KCC addon is installed as a Unity package from the Photon UPM Git repository, see Packages/manifest.json.

The project has four scenes:

  • 00_MainMenu: The main menu, the first scene of a build.
  • 01_ThirdPersonCharacter: A prototype environment.
  • 02_Platformer: A platformer level with coins, falling platforms and the flag.
  • 03_Shooter: A shooter arena with eight spawn points and the ChickenSpawner.

The NetworkRunner does not switch scenes, UIGameMenu passes the active scene to StartGame and reloads it after a disconnect, see Scene Loading.

High Level Breakdown

The game boots in the 00_MainMenu scene, UIMainMenu loads an example scene by build index when a button is pressed. Every example scene contains the UIGameMenu prefab, it shows the game menu and starts the session with GameMode.AutoHostOrClient, see Session and Menu.

In the Client Host topology one client is the host and has state authority over all network objects, the other clients send their input and predict the result, see Fusion Introduction. Game logic that changes networked state runs on the state authority, the scripts check HasStateAuthority before they spawn players, collect coins or apply damage. The same three examples exist as a Shared Authority project, see Architecture - Shared Authority.

Third Person Character spawns a player object per connected player and moves it with the Simple KCC addon.

Platformer adds coins, falling platforms and a race to the flag.

Shooter adds a hitscan weapon with lag compensation, health and flying chickens.

Session and Menu

UIGameMenu.StartGame instantiates the Runner prefab and starts the session:

C#

var startArguments = new StartGameArgs()
{
    GameMode = Application.isEditor && ForceSinglePlayer ? GameMode.Single : GameMode.AutoHostOrClient,
    SessionName = RoomText.text,
    PlayerCount = MaxPlayerCount,
    // We need to specify a session property for matchmaking to decide where the player wants to join.
    // Otherwise players from Platformer scene could connect to ThirdPersonCharacter game etc.
    SessionProperties = new Dictionary<string, SessionProperty> { ["GameMode"] = GameModeIdentifier },
    Scene = sceneInfo,
};

GameModeIdentifier is set per scene to ThirdPersonCharacter, Platformer or Shooter, so matchmaking only joins sessions of the same example, see Network Runner. With GameMode.AutoHostOrClient the first client of a session becomes the host and later clients connect to it, see Network Topologies. After a disconnect or an unexpected shutdown the active scene is reloaded to reset the scene network objects.

Input

Each example has its own PlayerInput script and GameplayInput struct. The struct implements INetworkInput:

C#

public struct GameplayInput : INetworkInput
{
    public Vector2 LookRotation;
    public Vector2 MoveDirection;
    public NetworkButtons Buttons;
}

On the input authority PlayerInput accumulates the input actions in Update and hands the struct to Fusion in OnInput, see Client-Server Player Input. Player reads the struct with GetInput in FixedUpdateNetwork and detects a press by comparing Buttons with the networked previous buttons, so a jump is neither lost nor repeated when input is missing.

The touch controls live in the UIGameMenu prefab under MobileControls. OnScreenStick and OnScreenButton components are bound to the gamepad controls, OnScreenLook and OnScreenDoubleTap in Common/Scripts add camera look by dragging and a jump by double tap.

Third Person Character

GameManager implements IPlayerJoined and IPlayerLeft. On the state authority it spawns the Player prefab for every joining player and gives the player input authority, see Spawning. When a player leaves, the host despawns the object.

Player moves the character with the Simple KCC addon in FixedUpdateNetwork. The move velocity, the jump state and the previous buttons are networked properties, so the state is correct during resimulation on predicting clients. When input is missing, Player continues the KCC movement with zero desired velocity, so a falling character lands on the host and on the clients alike.

Third Person Character example
Third Person Character example

Platformer

Coin is a scene network object with a trigger that is enabled on the state authority only. When a player enters a coin, Player.OnTriggerEnter calls Coin.Collect and raises the networked CollectedCoins, Collect starts a TickTimer that hides the coin for RefreshTime seconds. The OnChangedRender callback on CollectedCoins plays the collect sound, see Change Detection.

FallingPlatform starts a fall timer when a player enters its trigger on the state authority. The script calls Runner.SetIsSimulated(Object, true) in Spawned, so FixedUpdateNetwork runs on all clients and the collider state is predicted.

When a player enters the Flag on the state authority, GameManager.OnFlagReached checks MinCoinsToWin, stores the networked Winner and starts the GameOverTimer. When the timer expires, all players respawn at the start with their coins reset. The nickname travels from the input authority to the state authority with RPC_SetNickname in Spawned, see RPCs.

Platformer example
Platformer example

Shooter

ChickenSpawner spawns 20 chickens on the state authority and respawns them after their death timer. Nothing in the spawner is networked because only the state authority uses it. Chicken moves in FixedUpdateNetwork, its position is replicated with a Network Transform.

Players and chickens both use the Health component, TakeHit lowers the networked CurrentHealth and starts the death timer. Render shows the death visuals based on the interpolated health value read with NetworkBehaviourBufferInterpolator, so a death is shown after the host confirmed it, see Network Buffers.

Player.Fire casts a lag compensated ray from the camera handle and applies damage to the Health of the hit HitboxRoot, see Lag Compensation:

C#

var hitOptions = HitOptions.IncludePhysX | HitOptions.IgnoreInputAuthority;

// Whole projectile path and effects are immediately processed (= hitscan projectile)
if (Runner.LagCompensation.Raycast(CameraHandle.position, CameraHandle.forward, 200f,
        Object.InputAuthority, out var hit, HitMask, hitOptions, QueryTriggerInteraction.Ignore) == true)
{
    // Deal damage
    var health = hit.Hitbox != null ? hit.Hitbox.Root.GetComponent<Health>() : null;
    if (health != null && health.TakeHit(1))
    {
        if (health.IsAlive == false)
        {
            // Killing chicken grants 1 point, killing other player has -10 points penalty.
            ChickenKills += health.GetComponent<Chicken>() != null ? 1 : -10;
        }
    }

The networked _fireCount, _hitPosition and _hitNormal drive the fire effects in Render on all clients. ShowFireEffects compares the fire count with a local counter instead of using OnChangedRender, so a mispredicted shot that the host rejects plays no effects. Lag compensation is enabled in the NetworkProjectConfig of the project.

Shooter example
Shooter example

Where to Go Next

After the Third Person Character, the Animations technical sample shows how to network character animation. The Simple KCC and Advanced KCC sample projects go deeper into character movement. BR200 uses third person controls and tick-based animations in an advanced sample.

After the Platformer, the Multi Climb tutorial builds a platformer with the Advanced KCC addon, movement abilities and a complete game loop. The KCC sample projects show movement affectors such as jump pads, force fields and surfaces. Razor Madness is a 2D platformer.

After the Shooter, Projectiles Essentials compares the ways to network projectiles. Simple FPS adds a complete game loop, weapons, ammo, pickups, player statistics and a leaderboard. Projectiles Advanced covers homing, ricocheting and spray projectiles and grenades. BR200 shows large player counts with sub-tick accurate shooting.

For a complete game, Tanknarok is a tank arena for up to four players with a lobby, rounds, scoring, powerups and networked projectiles. It ships as a Client Host and a Shared Authority project.

Back to top