今回は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」という表示が出たり出なかったりになるので、そこで察する感じでひとつ。
