Using UniRx plus UniRx.Async to implement asynchronous loading of AddressableReference

Because the loading of Addressable resources is performed asynchronously, the general way of writing is to add a callback. The following is one way of writing:

public static void LoadAsync<T>(string address, UnityAction<AsyncOperationHandle<T>> endCb)
{
    Addressables.LoadAssetAsync<T>(address).Completed() += endCb;
}

In addition, you can use await/async to achieve:

public static async Task<T> LoadAsync<T>(string address)
{
    var handle = Addressables.LoadAssetAsync<T>(address);
    await handle.Task;
    return handle.Result;
}

However, this implementation method will cause a situation, that is, when I implement it in the following two ways, the results are different:

private void Start()
{
    m_Sprite = LoadAsync<Sprite>("ssss");
    SetSprite();
}

private async void SetSprite()
{
    var task = LoadAsync<Sprite>("ssss");
    await task;
    m_Sprite = task.Result;
}

When the function executes to line 3, it will get stuck because it thinks it needs to wait for a data to be obtained. However, the task never returns data, so the program gets stuck and Unity crashes. Only the method in line 4 can be used. Normal retrieval, but this means that you have to write many layers of nesting to truly handle data retrieval (using return is similar), so at this time I thought of using UniRx to handle this asynchronous programming.
I won’t go into detail here about what UniRx is. UniRx.Async is an asynchronous logic officially expanded to support C#’s new feature await/aysnc. It also uses a UniTask similar to Task, but it has much richer functions, and UniTask has ToObserveable method, which can be used to achieve very easy asynchronous processing:

public async UniTask<T> LoadAsync<T>(string address)
{
    var handle = Addressables.LoadAssetAsync<T>(address);
    await handle.Task;
    return handle.Result;
}
private void Start(){
    var task = LoadAsync<Sprite>("ssss");
    task.ToObservable().Subscribe(res => { image.sprite = res; });
}

You can see that the writing method of UniTask itself is the same as that of Task. Using this method, we do not need to write a lot of asynchronous or callbacks. When LoadAsync is executed, the method in Subscribe will be called. I have not studied the efficiency, but according to official and private According to the data survey, it should be good. The article I read by Yusong Mono also mentioned its benefits. For more information, please go to the official website: https://github.com/Cysharp/UniTask#license UniRx itself can be downloaded from UnityAssetStore, and UniRx.Async can be downloaded from the link given above (both must be present) ).

Guess you like

Origin blog.csdn.net/qq_37421018/article/details/103023943