【PUN】PhotonCloudのコールバック処理をUniRxでスマートに書く「PhotonRx」

More than 1 year has passed since last update.

PhotonRx

PUNのコールバック通知をUniRxのObservableTriggerの形式で扱えるようにしてみました。

PhotonRx

ライセンスはMITです。

使い方

usingにPhotonRxを追加すれば、あとはthis.xxxxAsObservableの形式でコールバック通知をObservableとして扱えるようになります。

PhotonRxのサンプル
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ベースにしてしまえば扱いやすく、パフォーマンス的にも良いのでこれは早速使うしか無いなということで実装をしてみました。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.