seefood_diet / Assets / Scripts / SDAssetUtils.cs
SDAssetUtils.cs
Raw
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UniRx;
using UniRx.Triggers;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.ResourceManagement.AsyncOperations;

public static class SDAssetUtils {

    public static IObservable<T> LoadAssetAsync<T> (string address) where T : UnityEngine.Object {

        if (Application.isPlaying) {

            return Addressables.LoadAssetAsync<T> (address).ToObservable ();
        } else {

#if UNITY_EDITOR
            return Observable.Return<T> (UnityEditor.AssetDatabase.LoadAssetAtPath<T> (address));
#endif
            return null;
        }
    }

    public static IObservable<GameObject> InstantiateAsync (string address, Transform parent, bool getComponentInChildren = false) {

        if (Application.isPlaying) {

            return Addressables.InstantiateAsync (address, parent)
                .ToObservable ();
        } else {

#if UNITY_EDITOR
            return LoadAssetAsync<GameObject> (address)
                .Select (asset => GameObject.Instantiate (asset, parent));
#endif

            return null;
        }
    }

    public static IObservable<T> InstantiateAsync<T> (string address, Transform parent, bool getComponentInChildren = false) {

        if (Application.isPlaying) {

            return Addressables.InstantiateAsync (address, parent)
                .ToObservable ()
                .Select (obj => {

                    return getComponentInChildren ? obj.GetComponentInChildren<T> () : obj.GetComponent<T> ();
                });
        } else {

#if UNITY_EDITOR
            return LoadAssetAsync<GameObject> (address)
                .Select (asset => {

                    var obj = GameObject.Instantiate (asset, parent);
                    return getComponentInChildren ? obj.GetComponentInChildren<T> () : obj.GetComponent<T> ();
                });
#endif

            return null;
        }
    }
}

public static class SDUnityActionExtensions {

    public static IObservable<TResult> ToObservable<TResult> (this UnityAction<TResult> action) {

        return Observable.FromEvent<UnityAction<TResult>, TResult> (
            h => h.Invoke,
            h => action += h,
            h => action -= h
        );
    }
}

public static class SDAsyncOperationHandleExtensions {

    public static IObservable<TResult> ToObservable<TResult> (this AsyncOperationHandle<TResult> handle) {

        return Observable.FromCoroutine<TResult> (o => TaskCoroutine (o, handle.Task));
    }

    static IEnumerator TaskCoroutine<TResult> (IObserver<TResult> observer, Task<TResult> task) {

        while (!task.IsCompleted) {

            yield return null;
        }

        observer.OnNext (task.Result);
        observer.OnCompleted ();
    }
}