【UniRx】DomainReloadに対応する

エディタ上でゲームを再生するまでの時間を高速化する「Configurable Enter Play Mode」ですが、チェックを入れるだけで有効化でき、ゲームの再生がかなり高速化します。

設定はだいたいネットに転がってる以下のように設定していると思います。

Project Settinsgs > Editor > Enter Play Mode Settings

Enter PlayMode Options [x]
  Relaod Domain        [ ]
  Reload Scene         [x]

で、タイトルの件ですが UniRx がこの状態だと途中から上手く動かなくなります。これは「Relaod Domain」のチェックを外していると static 変数の初期化がスキップされるため発生する現象です。Reload Domain にチェック入れればいいですが遅くなるのでなるべくチェックは外したままにしたいところです。

なので、関係する各コード中に static 変数を初期化する必要があります。

一般的な初期化方法は以下の通りです。

static int count;

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void Setup()
{
    // static 変数の初期化
    count = 0; // 例えばこう
}

大抵 null や規定値に設定し直したり、カウンターをゼロに戻したりという事をここで行います。

修正内容

UniRx の具体的な修正方法ですが、以下2か所を修正します。

// UniRxのプルリクより
// <https://github.com/neuecc/UniRx/pull/480/files/5a95fbb0309b43a32ca91e1e25d300c693bb5e51>

// ~UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs
// 以下を追記する

#if UNITY_2019_3_OR_NEWER && UNITY_EDITOR
        // Clean up static properties for times when Domain Reload is disabled.
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
        static void DomainCleanup()
        {
            initialized = false;
            isQuitting = false;
            instance = null;
        }
#endif

もうひとつ

// ~/UnityEngineBridge/ScenePlaybackDetector.cs
// 以下をOnDidReloadScriptsメソッドの前に追記する

#if UNITY_2019_3_OR_NEWER && UNITY_EDITOR
        // This callback is notified when Unity initializes subsystems
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
#else
        // This callback is notified after scripts have been reloaded.
        [DidReloadScripts]
#endif
        public static void OnDidReloadScripts()

とすれば対応完了です。

UniRx は(2019年7月以来更新が無くて色々 issue が結構積まれてるのに放置状態ですが)event の代替機能として(恐らく相当先まで)有用なのでセルフメンテして使っていきましょう。今のところ自分でパッチ当てるのも特に難しくも無いですし。

参考資料

Unity: Configurable Enter Play Mode

https://docs.unity3d.com/ja/2022.2/Manual/ConfigurableEnterPlayMode.html

UniRxのプルリク#480

https://github.com/neuecc/UniRx/pull/480