This document is about: FUSION 1
SWITCH TO

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

5 - RPCs

概述

在上一個階段,一個已連網屬性被新增,以同步玩家顏色到所有其他玩家。因為玩家在它們自己的已連網屬性上有StateAuthority,它們可以直接地更新它們的顏色的值。

然而,這不適用於NetworkObjects的已連網屬性,在其中StateAuthority是另一個客戶端。

這個章節含有攻擊一個玩家及減少它們的健康的示例,在其中需要修改另一個玩家的已連網屬性。

修改其他玩家已連網屬性

更改另一個客戶端有State Authority的一個已連網屬性的方法,是發送一個RPC(遠端程序調用)到物件的StateAuthority,並且讓它們更改已連網屬性。

雖然可以透過程式碼來更改已連網屬性的值。該更改將只應用於本機,並且不會透過網路來複製。

這個的一個示例是以一個射線武器來射擊一個玩家。針對Fusion共享模式的這個的一個簡單的執行方式是,讓玩家在本機執行一個射線,並且如果它擊中一個目標的話,應用傷害到該目標。請注意,在伺服器/主機端模式中針對射線武器的方法是不同的。請查看Fusion拋射物範例以了解伺服器/主機端模式示例。

建立一個新的指令碼並且命名它為Health

C#

using Fusion;
using UnityEngine;

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

下一步是新增一個RPC,其中射手可以調用它以對敵方玩家造成傷害:

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允許任何人來調用RPC。預設下,只有InputAuthority(與共享模式中的StateAuthority相同)可以調用一個RPC。

RpcTargets.StateAuthority所做的是,只有StateAuthority接收RPC。完成這個,因為StateAuthority隨後將更新Health已連網屬性。在RPC函數中的程式碼運行在RpcTarget客戶端上,因此在這個案例中運行在StateAuthority上,其可以更改自己的已連網屬性。

下一步是建立一個新的指令碼並且命名它為RaycastAttack。新增以下程式碼到它:

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);
        }
    }
}

這個程式碼是射線的一個直觀的單一玩家執行方式。HasStateAuthority檢查只用於在StateAuthority上執行這個程式碼,因此當玩家按下發射按鈕時,只有它們自己的玩家角色發射一個射線。

現在為了應用傷害到目標,剩下需要做的是在其上調用RPC函數。在Debug.DrawRay列之後,新增以下內容:

C#

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

有了這些,已經可以射擊一個射線及造成傷害。剩下需要做的是針對Health已連網屬性的更改作出回應。回到Health指令碼並且新增一個在更改時回調:

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}");
}

有了這個程式碼,新增HealthRaycastAttack元件到玩家預製件並且新增一個組建。

其他RPC使用案例

要求狀態授權來修改已連線屬性,是最常見的RPC使用案例。

其他有效的的RPC使用案例包含:

  1. 在玩家之間發送一個嘲弄訊息、表情符號或其他動態的非遊戲遊玩互動。
  2. 啟動一個遊戲(在遊戲模式、地圖上投票,或只是讓主機端知道玩家已經準備好)。

在大多數使用案例中,狀態同步本身就足以讓玩家保持一致,而新增一個更改偵測器到一個已連網屬性可以處理大多數的過渡案例,在其中應用程式關注狀態中的更改,而不僅僅是實際的狀態本身。

遊玩遊戲

恭喜!您已經成功地完成Fusion 105教學。為了確保所有功能都正確運行,現在是時候遊玩及測試遊戲。

在Unity中啟動一個組建並且輸入遊玩模式,並且按下Start Shared Client。以右鍵按一下其他玩家,將在一個膠囊中顯示訊息,其顯示它們的健康的減少。

您也可以在Unity中的階層檢查器中查看已連網屬性的Health值。

下一章是共享模式基礎6 - 下一步是什麼

Back to top