fusion | v2 switch to V1  

5 - RPC

概要

前回のセクションで、ネットワークプロパティを追加してその他すべてのプレイヤーと、プレイヤーの色を同期しました。 プレイヤーのネットワークプロパティ上でStateAuthorityがあるので、 プレイヤーは直接色の値を更新できます。

ただし、これはNetworkObjectsのネットワークプロパティには効果がありません。 StateAuthority が別のクライアントだからです。

このセクションでは、他のプレイヤーのネットワークプロパティの修正が必要な、プレイヤーを攻撃したりヘルスを減らしたりする例をお見せしています。

他のプレイヤーのネットワークプロパティを修正する

他のクライアントがState Authorityを持っている場合のネットワークプロパティの変更方法は、オブジェクトの StateAuthority へRPC(リモートプロシージャコール)を送信して、ネットワークプロパティを変更させることです。

コードでネットワークプロパティの値を変更することは可能です。 変更が適用されるのはローカルだけで、ネットワークで複製されません。

この例は、レイキャストウェポンでプレイヤーを撃つことです。 Fusion Sharedモードで簡単に実装する簡単な方法は、プレイヤーがレイキャストをローカルに実行して、ターゲットにヒットしたときにそのターゲットにダメージを与えることです。 Serverモード・Hostモードでのレイキャストウェポン方式はまた異なりますのでご注意ください。 Serverモード・Hostモードの例については、 Fusion Projectiles Sample を参照してください。

新しくスクリプトを作成して Healthと名前を付けます。

using Fusion;
using UnityEngine;

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

次に、シューターが呼び出しを行い敵のプレイヤーへのダメージを処理するRPCを追加します。以下を参照してください。

    [Rpc(RpcSources.All, RpcTargets.StateAuthority)]
    public void DealDamageRpc(float damage)
    {
        // ここで表記しているコードは、このオブジェクト(ステート、インプットオーソリティ)を持つクライアントを実行します。
        Debug.Log("Received DealDamageRpc on StateAuthority, modifying Networked variable");
        NetworkedHealth -= damage;
    }

RpcSources.Allで、誰でもRPCを呼び出せるようになります。

​デフォルトでは、RPCを呼び出せるのはInputAuthorityのみ(Shared モードのStateAuthorityと同様)でした。

RpcTargets.StateAuthorityで、StateAuthorityのみがRPCを受け取るようにしています。 ​ StateAuthorityHealthネットワークプロパティを更新できるように、この手順を実行しています。 RPC関数内のコードはRpcTargetクライアント上で実行されます。このケースでは、自分でネットワークプロパティを変更できるStateAuthorityでの実行となります。

次に、新しくスクリプトを作成して、 RaycastAttackと名前を付けます。 以下のコードを追加します。

using Fusion;
using UnityEngine;

public class RaycastAttack : NetworkBehaviour
{
    public float Damage = 10;
    
    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の次に、以下を付け足します。

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

以上をもって、レイキャストウェポンの発射とダメージ処理がゆうこうになります。 あとは、 Healthネットワークプロパティに変更を反映させます。 Healthスクリプトに戻り、OnChangedCallbackを追加します。


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

private static void NetworkedHealthChanged(Changed<Health> changed)
{
    // ここでコードを追加してプレイヤーのヘルスバーを更新します。
    Debug.Log($"Health changed to: {changed.Behaviour.NetworkedHealth}");
}

以上を行ったら、Health および RaycastAttackコンポーネントをプレイヤープレハブに追加してビルドを作成します。

その他の RPC ユースケース

RPCで最もよく見られるユースケースは、ステートオーソリティにネットワークプロパティを変更するように依頼することです。

その他にも以下のようなユースケースがみられます。

  1. 挑発メッセージ、エモート、その他ゲームプレイとは異なるプレイヤー間の一時的なやりとりの送信。
  2. ゲームの起動(ゲームモード、マップでの投票、またはホストにプレイヤーの準備完了を伝える、など)

ほとんどのケースで、プレイヤーの足並みをそろえるにはステート同期のみで十分です。ネットワークプロパティに変更検知を追加することで、トランジショナルなケース(アプリケーションが、実際のステートのみならずステートでの変更の影響を受けるケース)に対応できるようになります。

ゲームをプレイする

お疲れさまでした!

​ Sufion Sharedモードのベーシックチュートリアルを無事に完了しました。 全てが適切に機能していることを確認するため、ゲームをプレイしてテストしましょう。

Unityでビルドを起動してプレイモードに入り、Start Shared Clientを押します。 他のプレイヤーを右クリックすると、コンソールにメッセージが表示され、ヘルスが減っていることがわかります。

Unityのヒエラルキーインスペクターでも、ネットワークプロパティのHealth値を確認できます。

次は Shared Mode Basics 6 - 次の目的です。

ドキュメントのトップへ戻る