#PhotonRx
PUNのコールバック通知をUniRxのObservableTriggerの形式で扱えるようにしてみました。
ライセンスはMITです。
##使い方
usingにPhotonRxを追加すれば、あとはthis.xxxxAsObservableの形式でコールバック通知をObservableとして扱えるようになります。
using System;
using PhotonRx; //追加する
using UnityEngine;
using UniRx;
public class PhotonRxSamle : MonoBehaviour {
void Start ()
{
//プレイヤの入室イベント
this.OnPhotonPlayerConnectedAsObservable()
.Subscribe(p => Debug.Log(p.name + "さんが入室しました"));
//プレイヤの退室イベント
this.OnPhotonPlayerDisconnectedAsObservable()
.Subscribe(p => Debug.Log(p.name+"さんが退室しました"));
}
}
PhotonRxで定義されているxxxAsObservable()はObservableTriggerBaseと同じ挙動になっています。
つまり、対象のGameObjectが破棄されると自動的にOnCompletedが飛ぶようになっているのでストリームの寿命管理も考えなくて良くなっています。
##PhotonRxを導入するメリット
- PhotonのコールバックがIDE補完が効く形で呼び出せるようになる
- 型安全に扱えるようになる
- UniRxの柔軟な非同期処理にそのまま載せることができる
##高度な使い方
PhotonRxとコルーチンを組み合わせると非同期処理を同期処理っぽく書けるようになります(awaitみたいなことができる)
using System;
using System.Collections;
using PhotonRx;
using UnityEngine;
using UniRx;
public class PhotonRxSamle2 : MonoBehaviour
{
private void Start()
{
//ロビーへの接続処理
StartCoroutine(ConnectCoroutine());
}
private IEnumerator ConnectCoroutine()
{
//ロビーへの接続結果を通知するストリームを作成
//接続成功・失敗のストリームの2つをマージしてどちらかのイベント通知の到達を待つ
var loginStream = this.OnJoinedLobbyAsObservable().Cast(default(object))
.Merge(this.OnFailedToConnectToPhotonAsObservable().Cast(default(object)))
.FirstOrDefault() //OnCompletedを発火させるため
.PublishLast(); //PublishLastは結果をキャッシュする
//ConnectでStartAsCoroutineより前にストリームの監視を開始する
loginStream.Connect();
//接続開始
PhotonNetwork.ConnectUsingSettings("0.1");
//結果保存用のオブジェクト
var result = default(object);
//StartAsCoroutineは対象のストリームのOnCompletedが発行されるまでnullを返す(コルーチン上で待機する)
yield return loginStream.StartAsCoroutine(x => result = x, ex => { });
//結果の型を見て判定する
if (result is DisconnectCause)
{
Debug.Log("接続失敗");
//
//ここに失敗処理を書く
//
yield break;
}
Debug.Log("接続成功");
//以下処理を続けるならここに書く
}
}
肝はStartAsCoroutine
です。
詳しくは【UniRx】UniRxとコルーチンをご参考ください。
##作った経緯
6/19のUniRx勉強会で講演された、gloopsの森永さんの若輩エンジニアから見たUniRxを利用したゲーム開発というスライドの中で、ObservableTriggerとしてPUNのコールバックを扱うと便利に幸せになったとの内容がありました。
確かにTriggerベースにしてしまえば扱いやすく、パフォーマンス的にも良いのでこれは早速使うしか無いなということで実装をしてみました。