Skip to content

202 3 離散的な値の同期方法

miuccie miurror edited this page Jan 17, 2020 · 15 revisions

202-3 - 離散的な値の同期方法


イベント同期 - RPC(リモートプロシージャコール)

Photonではサーバーを介して他クライアントのメソッドを呼び出すことによる同期も可能です。これは一般にRPCと呼ばれる同期方法になります。

RPCはイベントなどの離散的な値を同期させるのに向いています。
PhotonでRPCによる同期を行うには、以下のメソッドを使用します。

PhotonView.Get(PhotonViewインスタンス).RPC( ”イベントハンドラ名”, RpcTarget.All, args )

RPCリファレンス
https://doc.photonengine.com/ja-jp/pun/v2/gameplay/rpcsandraiseevent

RPCも、PhotonViewに紐づいたオブジェクトを経由しないと呼べません。
また受信するハンドラを実装するスクリプト側も、発信する側と同じPhotonViewと紐づいている必要があります。

また引数のRpcTarget Enumでは、RPCの送信相手とそのバッファリング方法を指定できます。 Bufferedを指定すると、サーバー側で過去のRPCの履歴を保持することで、後からルームに入ってきたプレイヤーにも最新の状態での同期が可能になります。またViaServerでサーバーを経由させると、イベントの発火順序が保証されるようになります。

enum RpcTarget {
  All, Others, MasterClient, 
  AllBuffered, OthersBuffered, 
  AllViaServer, AllBufferedViaServer
}

RpcTargetリファレンス
https://doc-api.photonengine.com/en/pun/v2/group__public_api.html#ga7c6a0c7a9a36c014e9c416ffaeef8b9b

現在のRPCによる同期に使用できるデータ型は下記になるようです。

  • byte, int, float
  • byte[], int[], float[]
  • string, string[]
  • Vecter3, Quaternion

プレイヤーの色の同期

ここでは自プレイヤーのアバターの色を一定間隔でランダムに変更し、その変更をRPCを使って同期してみます。
Avatarスクリプトの一部を下記のように変更してください。

    //------------------------------------------------------------------------------------------------------------------------------//
    void Start () {

      // このオブジェクトはPhotonInstanciate()から生成される
  	// Start()は他クライアント所有のオブジェクトが自動で生成された場合にも呼ばれるので注意

        // 自クライアント所有のオブジェクトの場合のみ実行
        if( photonView.IsMine ){

	    //アバターの名前を変更する
	    ChangeMyName( "Player-No:" + PhotonNetwork.LocalPlayer.ActorNumber );

            //定期的にアバターの色を変更する
            StartCoroutine( "ChangeMyColor" );
        }
    }

---

    //------------------------------------------------------------------------------------------------------------------------------//
    // RPCによるイベントの同期
    //------------------------------------------------------------------------------------------------------------------------------//
    IEnumerator ChangeMyColor(){

        while(true){

           //定期的に自分の色を変更する

            //自クライアントを含めた全クライアントに送信 / バッファリングはしない
            Vector3 color = new Vector3( Random.value, Random.value, Random.value );
            PhotonView.Get(this).RPC( "OnChangeMyColor", RpcTarget.All, color );

            yield return new WaitForSeconds( 2f );
        }
    }

    [PunRPC]
    void OnChangeMyColor( Vector3 color ){

        // 色の変更を反映する
        this.GetComponent<Renderer> ().material.color = new Color( color.x, color.y, color.z );
    }

受信ハンドラ側は、C#のattributeを使用して、[RPC]属性を付加していることに注意してください。


イベント同期の確認

2つのクライアントを起動して実行してみてください。一方のクライアントで変更された自アバターの色が、別クライアント上にも反映されたでしょうか。

またRpcTargetの値を色々と変更してみて、バッファリングがどのように機能するか確認してみてください。

RPCを使用することで、イベント発行時のタイミングでの同期や、そのタイミングに合わせた値の同期が可能になります。

またここでは触れませんが、自前のイベントを定義して、それをレイズすることでイベント同期を可能にする方法もあります。 カスタムイベントを実装する場合は、下記を参照してください。 https://doc.photonengine.com/ja-jp/pun/v2/gameplay/rpcsandraiseevent


講義で実装したマルチプレーヤー対応は下記シーンにまとめて収められています
https://github.com/yumemi-inc/vr-studies/tree/master/vol2/VR-studies/Assets/VR-studies/1_MultiPlayer/MultiPlayer.unity