Help us understand the problem. What is going on with this article?

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

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

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away