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を受け取るようにしています。
StateAuthority
がHealth
ネットワークプロパティを更新できるように、この手順を実行しています。 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で最もよく見られるユースケースは、ステートオーソリティにネットワークプロパティを変更するように依頼することです。
その他にも以下のようなユースケースがみられます。
- 挑発メッセージ、エモート、その他ゲームプレイとは異なるプレイヤー間の一時的なやりとりの送信。
- ゲームの起動(ゲームモード、マップでの投票、またはホストにプレイヤーの準備完了を伝える、など)
ほとんどのケースで、プレイヤーの足並みをそろえるにはステート同期のみで十分です。ネットワークプロパティに変更検知を追加することで、トランジショナルなケース(アプリケーションが、実際のステートのみならずステートでの変更の影響を受けるケース)に対応できるようになります。
ゲームをプレイする
お疲れさまでした!
Sufion Sharedモードのベーシックチュートリアルを無事に完了しました。 全てが適切に機能していることを確認するため、ゲームをプレイしてテストしましょう。
Unityでビルドを起動してプレイモードに入り、Start Shared Client
を押します。 他のプレイヤーを右クリックすると、コンソールにメッセージが表示され、ヘルスが減っていることがわかります。
Unityのヒエラルキーインスペクターでも、ネットワークプロパティのHealth
値を確認できます。