今回はPhotonを使ったメッセージの送受信をやってみます。
チュートリアルは以下のページを参考にしています。
叫び声を設定する
チュートリアルの流れにそって、RPCを使って表示されてるモンスターに鳴き声を上げさせるようにしてみます。
まず再生するための音源を適当に用意します。Unityで使える音源なら何でもな感じで。チュートリアルのほうでは、自動生成するサイトへのリンクがあってそちらでもよいですが、わかりやすくフリーで用意されてる音源を探してきました。
こちらの「ドラゴン・鳴き声02」と「ドラゴン・咆吼01」をサンプルとして使います。ダウンロードして、MarcoPoloフォルダにドラッグ&ドロップしておいてください。
RPCを受信するメソッドを作る
MarcoPoroフォルダに、「AudioRpc」というスクリプトを作り、以下のように入力します。
using UnityEngine; using System.Collections; public class AudioRpc : MonoBehaviour { public AudioClip marco; public AudioClip polo; [PunRPC] void Marco() { Debug.Log("Marco"); this.GetComponent<AudioSource>().clip = marco; this.GetComponent<AudioSource>().Play(); } [PunRPC] void Polo() { Debug.Log("Polo"); this.GetComponent<AudioSource>().clip = polo; this.GetComponent<AudioSource>().Play(); } }
チュートリアルではthis.audioを参照しているのですが、今のUnityではGetCompornentで取得するようになっているみたいです。
あと属性も「RPC」ではなく「PunPRC」にしています。UnityのRPCは廃止されていくみたい。
これによって、RPCでMarcoメソッドが呼ばれたときにはmarcoのオーディオが、Poloメソッドが呼ばれたときにはpoloのオーディオが再生されます。
次にこのスクリプトをmonsterprefabに追加して、「Marco」のオーディオクリップに「ドラゴン・鳴き声02」を、「Polo」のオーディオクリップに「ドラゴン・咆吼01」をドラッグ&ドロップ。
またmonosterprefabにAudioSourceコンポーネントを追加します。これが無いと、
MissingComponentException: There is no 'AudioSource' attached to the "monsterprefab(Clone)" game object, but a script is trying to access it.
You probably need to add a AudioSource to the game object "monsterprefab(Clone)". Or your script needs to check if the component is attached before using it.
が発生します。
これで再生の準備は整いました。
鳴き声を上げさせるボタンを付ける
上で設定した鳴き声をモンスターに上げさせるためのボタンをRandomMatchmakerに追加します。
まずRPCを送信するためにはPhotonViewのインスタンスが必要なので、それを保持するメンバ変数myPhotonViewを追加。
private PhotonView myPhotonView;
で、JoinしたときにPhotonViewを取得します。
public override void OnJoinedRoom() { GameObject monster = PhotonNetwork.Instantiate("monsterprefab", Vector3.zero, Quaternion.identity, 0); monster.GetComponent<myThirdPersonController>().isControllable = true; myPhotonView = monster.GetComponent<PhotonView>(); }
myPhotonViewへPhotonViewを保存します。
最後に、これを通してRPCを送信するためのGUIボタンを追加します。
void OnGUI() { GUILayout.Label(PhotonNetwork.connectionStateDetailed.ToString()); if (PhotonNetwork.connectionStateDetailed == ClientState.Joined) { if (GUILayout.Button("Marco!")) { this.myPhotonView.RPC("Marco", PhotonTargets.All); } if (GUILayout.Button("Polo!")) { this.myPhotonView.RPC("Polo", PhotonTargets.All); } } }
OnGUIを上のように変更。
チュートリアルページではPeerState.Joinedを参照していますが、これがPhotonの1.67ではあったけど1.77では無くなっているみたいなので、ClientState.Joinedを使用しています。
あとは実行してみると、ボタンが左上に置いてあるので、
押してみると、ログインしている全端末から音が鳴ります!
フォアグラウンドにあるアプリでのみ有効にする
例えば実行ファイルとエディタなど、同じPCで2つ以上のクライアントを実行させてテストしている場合、このボタンを押すと両方のアプリから音が鳴ってしまいます。
そこで、フォアグラウンドでいるときのみ、音を鳴らすようにします。
AudioRpcのコードに、アプリケーションのフォーカスで自身を有効/無効にするコードを追加して、
void OnApplicationFocus(bool focus) { this.enabled = focus; }
MarcoとPoloで、enabledを見るようにします。
[PunRPC] void Marco() { if (!this.enabled) { return; } Debug.Log("Marco"); this.GetComponent<AudioSource>().clip = marco; this.GetComponent<AudioSource>().Play(); } [PunRPC] void Polo() { if (!this.enabled) { return; } Debug.Log("Polo"); this.GetComponent<AudioSource>().clip = polo; this.GetComponent<AudioSource>().Play(); }
一つのマシンでやってるとわかりづらいかもしれませんが…Consoleに「Marco」という表示が出たり出なかったりになるので、そこで察する感じでひとつ。