はじめに
SceneManager.sceneLoaded
をIObservable
にしようと思ったら型パズルで苦戦したのでメモ1。
コード
ObservableSceneEvent.cs
using System;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
namespace UniRx
{
public static class ObservableSceneEvent
{
public static IObservable<Tuple<Scene, Scene>> ActiveSceneChangedAsObservable()
{
return Observable.FromEvent<UnityAction<Scene, Scene>, Tuple<Scene, Scene>>(
h => (x, y) => h(Tuple.Create(x, y)),
h => SceneManager.activeSceneChanged += h,
h => SceneManager.activeSceneChanged -= h
);
}
public static IObservable<Tuple<Scene, LoadSceneMode>> SceneLoadedAsObservable()
{
return Observable.FromEvent<UnityAction<Scene, LoadSceneMode>, Tuple<Scene, LoadSceneMode>>(
h => (x, y) => h(Tuple.Create(x, y)),
h => SceneManager.sceneLoaded += h,
h => SceneManager.sceneLoaded -= h
);
}
public static IObservable<Scene> SceneUnloadedAsObservable()
{
return Observable.FromEvent<UnityAction<Scene>, Scene>(
h => h.Invoke,
h => SceneManager.sceneUnloaded += h,
h => SceneManager.sceneUnloaded -= h
);
}
}
}
各イベントがstaticなせいで拡張メソッドとして実装できないので、苦肉の策でstaticなObservableSceneEvent
クラスを実装。
SceneManager
を完全にラップするObservableSceneManager
クラスの実装も考えたけどUnityのAPIが変わるごとにメンテナンスするのが面倒だったのでこの形に落ち着いた。
C#7以上を使ってる場合はTuple
を適当に書き換えてください(参考:タプル)。
参考
-
FromEvent()
はたまにしか書かないので全然覚えられない😂 ↩