はじめに
Unityのシーン遷移のObservableが欲しくなりました。
EveryUpdate のノリで使いたい。
この記事ではR3のEveryUpdate のノリで使えるシーン遷移Observableの作り方を紹介します。
シーン遷移イベント
SceneManager.activeSceneChangedというActiveシーンが切り替わったときに発火するstaticのEventがありました(公式ScriptReference)。引数は前のシーン(prev)と次のシーン(next)が渡されます。
Observableにする
以下のSceneChangeObservable.csにactiveSceneChangedをObservableにする関数を書きました。staticクラスなので、ゲームオブジェクトにアタッチする必要もありません。
using System.Threading;
using UnityEngine.SceneManagement;
using R3;
using UnityEngine.Events;
public static class SceneChangeObservable
{
public static Observable<(Scene prev, Scene next)> OnActiveSceneChangedAsObservable()
{
return OnActiveSceneChangedAsObservable(CancellationToken.None);
}
public static Observable<(Scene prev, Scene next)> OnActiveSceneChangedAsObservable(
CancellationToken cancellationToken)
{
return Observable.FromEvent<UnityAction<Scene, Scene>, (Scene, Scene)>(
h => (p, n) => h((p, n)),
h => SceneManager.activeSceneChanged += h,
h => SceneManager.activeSceneChanged -= h)
.TakeUntil(cancellationToken);
}
}
使い方
とりあえずR3を入れてください。
A, B, C の3つのシーンを用意してボタンを押すとA→B↔C というふうにシーン遷移するようにします。
ボタンは以下のSceneChangeButton.csをつけてよしなにしてください。ProjectSettingにシーンを登録すればnextNameに遷移したいシーンをインスペクターから設定できます。
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using R3;
public class SceneChangeButton : MonoBehaviour
{
[SerializeField] private string nextName;
private Button _button;
private void Start()
{
_button = GetComponent<Button>();
_button.OnClickAsObservable()
.Subscribe(_ => SceneManager.LoadScene(nextName))
.AddTo(this);
}
}
シーンAに空のオブジェクトを配置して以下のSceneChangeEventSubscriber.csをつけてシーン遷移イベントを受け取ります。EveryUpdate のノリで使えます。
ちなみにDontDestroyOnLoadしないとイベントを受け取れません。
using UnityEngine;
using R3;
using UnityEngine.SceneManagement;
public class SceneChangeEventSubscriber : MonoBehaviour
{
private void Start()
{
SceneChangeObservable.OnActiveSceneChangedAsObservable()
.Subscribe(tuple =>
{
Debug.Log($"Scene changed to {tuple.next.name}");
})
.AddTo(this);
DontDestroyOnLoad(gameObject);
}
}
実行
ボタンを押してシーンを切り替えるとSceneChangeEventSubscriber.csでログが出てきます。
まとめ
この記事ではR3のEveryUpdate のノリで使えるシーン遷移Observableの作り方を紹介しました。Unityパッケージ化したい。

