This document is about: FUSION 1
SWITCH TO

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

5 - RPCs

Overview

In the last section a Networked Property was added to synchronize the players colors to all other players. Since the player has StateAuthority over their own Networked Properties, they can directly update the value of their color.

However, this does not work for Networked Properties of NetworkObjects where the StateAuthority is another client.

This section contains an example for attacking a player and reducing their health where modifying another player's Networked Property is needed.

Modifying Other Player Networked Properties

The approach for changing a Networked Property over which another client has State Authority is to send an RPC (Remote Procedure Call) to the StateAuthority of the object and have them change the Networked Property.

While it is possible to change the values of the Networked Property by code. The change will be applied local only and not replicated over the network.

An example of this is shooting a player with a raycast weapon. A simple implementation of this for Fusion Shared mode is to have the player perform a raycast locally and if it hits a target apply damage to the target. Note that the approach for raycast weapons in Server/Host mode is different. Check the Fusion Projectiles Sample for a Server/Host mode example.

Create a new script and name it Health.

C#

using Fusion;
using UnityEngine;

public class Health : NetworkBehaviour
{
    [Networked]
    public float NetworkedHealth { get; set; } = 100;
}

Next add an RPC which the shooter can call to deal damage to the enemy player:

C#

    [Rpc(RpcSources.All, RpcTargets.StateAuthority)]
    public void DealDamageRpc(float damage)
    {
        // The code inside here will run on the client which owns this object (has state and input authority).
        Debug.Log("Received DealDamageRpc on StateAuthority, modifying Networked variable");
        NetworkedHealth -= damage;
    }

RpcSources.All allows anyone to call the RPC. By default, only the InputAuthority (same as StateAuthority in Shared mode) can call an RPC.

RpcTargets.StateAuthority makes it that only the StateAuthority receives the RPC. This is done because the StateAuthority will then update the Health Networked Property. The code inside the RPC function runs on the RpcTarget clients, so in this case on the StateAuthority which can change its own Networked Properties.

Next create a new script and name it RaycastAttack. Add the following code to it:

C#

using Fusion;
using UnityEngine;

public class RaycastAttack : NetworkBehaviour
{
    public float Damage;

    public PlayerMovement PlayerMovement;

    void Update()
    {
        if (HasStateAuthority == false)
        {
            return;
        }

        Ray ray = PlayerMovement.Camera.ScreenPointToRay(Input.mousePosition);
        ray.origin += PlayerMovement.Camera.transform.forward;

        if (Input.GetKeyDown(KeyCode.Mouse1))
        {
            Debug.DrawRay(ray.origin, ray.direction, Color.red, 1f);
        }
    }
}

This code is a straightforward single player implementation of a raycast. The HasStateAuthority check is used to only execute this code on the StateAuthority so that when a player presses the fire button only their own player character fires a raycast.

Now to apply damage to the target what's left is calling the RPC function on it. After the Debug.DrawRay line add the following:

C#

if (Runner.GetPhysicsScene().Raycast(ray.origin,ray.direction, out var hit))
{
    if (hit.transform.TryGetComponent<Health>(out var health))
    {
        health.DealDamageRpc(Damage);
    }
}

With that shooting a raycast weapon and dealing damage is already working. What's left is reacting to changes to the Health Networked Property. Return to the Health script and add a OnChangedCallback:

C#


[Networked(OnChanged = nameof(NetworkedHealthChanged))]
public float NetworkedHealth { get; set; } = 100;

private static void NetworkedHealthChanged(Changed<Health> changed)
{
    // Here you would add code to update the player's healthbar.
    Debug.Log($"Health changed to: {changed.Behaviour.NetworkedHealth}");
}

With that done, add the Health and RaycastAttack components to the player prefab and create a build.

Other RPC use cases

Asking the State Authority to modify Networked Properties is the most common use case for RPCs.

Other valid use cases for RPCs include:

  1. Sending a taunt message, emotes or other volatile non gameplay interaction between players.
  2. Launching a game (voting on gamemode, map, or just indicating to the host that a player is ready).

In most cases state synchronization itself is sufficient to keep players aligned, and adding a change detector to a networked property can handle most transitional cases where the application cares about a change in state and not just the actual state itself.

Playing the Game

Congratulations! You have successfully completed the Fusion 105 Tutorial. To ensure everything is functioning properly, it's now time to play and test the game.

Start a build and enter play mode in Unity and press Start Shared Client. Right-clicking on the other player displays messages in the console showing a reduction in their health.

You can also check the Health value of the Networked Property in the Hierarchy inspector in Unity.

Next Shared Mode Basics 6 - Where to go next

Back to top