[[キャラクタの同期(位置と回転のみ)|unity_photon_cloud_char_pos_rot]] > ---- !!![Photon Cloud] RPCで突発的にイベントを送る 「[[OnPhotonSerializeView|unity_photon_cloud_char_pos_rot]]」では、あらかじめ共有するキャラクタを前提に同期処理を行いましたが、突発的にイベントをRoom内の参加者に通知する場合はRPCが便利です。 たとえば、、、、 *音の再生 *条件が満たされたので、出口へのドアを開ける(フラグ解除) *単発のメッセージテキストを送る(チャット機能がPhotonCloudには存在するので、別段RPC使わなくてもよいですが) なお、音データや何かしらのフラグを解除する処理、などはあらかじめアプリのリソースとして「仕組み」は用意しておく必要があります。 !!RPCとは? プログラムで言うRPCは「Remote Procedure Call」の略になり、遠隔にあるルーチンや処理を呼び出す/実行する機能になります。 Photon Cloudの場合は、RPCとして明示された関数を呼びます。 !!簡単なRPCでの呼び出し 単純に、ボタンが押されたら何かしらのメッセージを表示する、という簡単な例で説明してみます。 !カラのGameObjectの作成と、PhotonViewの割り当て PhotonCloudを通してRPCを呼ぶための前処理として、カラのGameObjectをシーンに配置。「photon」という名称とします。 ここに、PhotonViewをComponentとして割り当てておきます。これがないとRPCは動作しません。 最終的に、photonという名称のGameObjectは「PhotonView」「PhotonCloudRPCTest」「RPCTest」の3つのスクリプトを持つことになります。 {{ref_image unity_photon_view_rpc_01.png}} !Photonの処理を行うスクリプトの記述 Photon.MonoBehaviour派生の「PhotonCloudRPCTest.cs」というのを作成。 これをGameObjectに割り当てます。 using UnityEngine; using System.Collections; public class PhotonCloudRPCTest : Photon.MonoBehaviour { private PhotonView m_photonView = null; public string messageText = ""; // Use this for initialization void Start () { PhotonNetwork.ConnectUsingSettings("0.1"); if (string.IsNullOrEmpty(PhotonNetwork.playerName)) { PhotonNetwork.playerName = "hoehoe"; } } // Update is called once per frame void Update () { } /** * Lobbyに入ったときに呼ばれる. */ void OnJoinedLobby() { // RoomにJoinする. PhotonNetwork.JoinRandomRoom(); } void OnPhotonRandomJoinFailed() { PhotonNetwork.CreateRoom("room1"); // Roomの生成. } /** * RoomへのJoinに成功. */ void OnJoinedRoom() { m_photonView = this.GetComponent(); } void OnGUI() { if (GUILayout.Button("Quit")) { Application.Quit(); return; } GUILayout.Label(PhotonNetwork.connectionStateDetailed.ToString()); if (GUILayout.Button("RPC Test")) { // 送信するメッセージテキスト. string playerName = PhotonNetwork.playerName; string playerID = (PhotonNetwork.player.ID).ToString(); string str = playerName + " / " + playerID; SendRPC(str); return; } if (GUILayout.Button("Clear Message")) { SendRPC(""); return; } GUILayout.Label("message : " + messageText); } /** * RPCで遠隔の関数を呼ぶ. */ private void SendRPC(string str) { if (m_photonView != null) { m_photonView.RPC("SendMessageTest", PhotonTargets.All, str); } } } Lobby/RoomへのJoinについては今までどおりですね。 OnJoinedRoom関数内で m_photonView = this.GetComponent(); として、同一GameObjectに割り当てている「PhotonView」を格納しています。 OnGUI関数で「RPC Test」ボタンが押されたときにSendRPC関数を呼んでます。この中で、 m_photonView.RPC("SendMessageTest", PhotonTargets.All, messageText); とすることで、PhotonView.RPC関数をキックします。 第一引数はRPCとして用意した関数名。 第二引数は送り先。PhotonTargets.Allを指定した場合はRoom内のすべてのPlayerに対して送ります。自分自身にもRPC経由の関数が呼ばれます。 第三引数以降は、呼ぶ関数の引数が存在する場合はそれを列挙していきます。この場合はstring型のテキストを渡しています。 !RPCの処理を行うスクリプトの記述 Photon.MonoBehaviour派生の「RPCTest.cs」というのを作成。 これをGameObjectに割り当てます。 ここでは、RPCで呼ばれる関数を列挙しています。 using UnityEngine; using System.Collections; public class RPCTest : Photon.MonoBehaviour { [RPC] void SendMessageTest(string message) { // 取得したメッセージを格納. GameObject photonG = GameObject.Find("/photon"); if (photonG == null) return; PhotonCloudRPCTest script = photonG.GetComponent(); if (script == null) return; script.messageText = message; } } [RPC]としたすぐ下に、呼び出す関数を記載。 これは、PhotonCloudRPCTestよりPhotonView.RPCが呼ばれた際に、遠隔地の関数として呼び出されます。 void SendMessageTest(string message) { // 取得したメッセージを格納. GameObject photonG = GameObject.Find("/photon"); if (photonG == null) return; PhotonCloudRPCTest script = photonG.GetComponent(); if (script == null) return; script.messageText = message; } この「SendMessageTest」関数はstring型の引数を1つ持ち、ここで受け取ったテキストをシーンの「/photon」のPhotonCloudRPCTestクラスのmessageText(string型)にテキストを格納しています。 テキストはPhotonCloudRPCTestクラス内のOnGUI関数で表示しているため、結果として各アプリの画面にこのテキストが表示されます。 これを複数アプリとして実行し、「RPC Test」ボタンを押すと、ボタンをプッシュしたPlayer名とPlayerIDが画面に表示されます。 「Clear Message」ボタンを押すと、表示されているテキストはクリアされます。 これがすべてのアプリで同期できているのが分かるかと思います。 ---- [[キャラクタの同期(位置と回転のみ)|unity_photon_cloud_char_pos_rot]] > ---- {{lastmodified}}