MRが楽しい

MRやVRについて学習したことを書き残す

UniRxのObserveOnMainThreadを使ってメインスレッドで処理を行う

本日はUniRxの小ネタ枠です。
UniRxのObserveOnMainThreadを使ってメインスレッドで処理を行う方法です。

前提条件

UniRxの環境構築手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com

ObserveOnMainThread

ObserveOnMainThreadはObservableの処理スレッドをUnityのメインスレッドへ切り替えます。

button.OnClickAsObservable().ObserveOnMainThread().Subscribe(_ => /*メインスレッド処理*/);

サンプルスクリプト

参照のボタン押下時にログを出力する以下のサンプルスクリプトを作成しました。
・OnClickTest.cs

using UnityEngine;
using UniRx;

public class MRTKUniRxOnMainThreadTest : MonoBehaviour
{
    [SerializeField]
    private Transform targetTransform;

    void Start()
    {
        Observable.Start(() =>
            {
                // 非同期処理
                Debug.Log("Working ThreadID:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
                System.Threading.Thread.Sleep(10000);
                return "Finished";
            })
            // メインスレッドで完了処理を呼び出し
            .ObserveOnMainThread()
            .Subscribe(text =>
            {
                Debug.Log("Result ThreadID:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
                Debug.Log("Value : " + text);
                // ターゲットオブジェクトを45度回転させる(メインスレッドでのみ動作)
                targetTransform.Rotate(0, 45, 0);
            })
            .AddTo(this);;
    }
}

シーンを再生するとオブジェクトの回転がメインスレッドで実行されます。

メインスレッドでオブジェクトの移動などを行うと以下のようなエラーが発生します。
このエラーが発生した場合は本オペレータを利用することで問題を回避できます。

UnityException: get_localRotation can only be called from the main thread.