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 (); } }