背景:unity中经常需要使用ui动画表现,特别是一些小游戏开发,特效动效少不了。如果都用回调会让代码看上去不那么线性,代码可读性会变得很差。unitask异步编程让这种异步发生在unity主线程中不会引起调用unity的mono对象从而导致unity崩溃,再则它比协程好在省去了"回调地狱",现在很多逻辑我已不在用协程了,除非是一些比较简单的逻辑,亦或是自己封装一个编辑器下的协程(本质是对迭代器对栈的封装)跑跑简单逻辑。对于复杂的异步操作还是建议使用unitask。

说明:ShowInInspector是自定义的按钮绘制,可以显示在mono的inspector面板中,点击该按钮即刻执行下方逻辑

unity unitask程序库取消unitask任务使用教程

注意点

1.注意点 try catch unitask必须是try await的异步逻辑 ,如果是_=是无法try到异常的 也就是他们必须在同一个函数栈中。

2.如果你的mono对象销毁了请手动cancel你的unitask任务,或者你的对象隐藏了,通常隐藏了对象unitask也就应该执行取消,如果是ui表现类的

具体还是取决于当时的业务需求。当然如果是业务逻辑比如状态改变了,你必须手动取消untask 在下面的代码中就是addBankerCoinTask.Cancel();

3.注意捕获unitask的异常是catch(OperationCanceledException e1) 当然如果内部有代码逻辑错误,也可以捕获到普通异常catch(Exception e2)

你的mono cs代码 
{
    CancellationTokenSource addBankerCoinTask = null;
    [ShowInInspector("测试捕货")]
    void TestDebugAddCoinAnim()
    {
        //注  _= 这种语法糖表示不阻塞当前逻辑,不用await了这个函数接口之后才执行后续逻辑,
        // 对于这里的逻辑即是定时器立即注册了任务并在2秒后执行回调逻辑取消unitask任务 
        // 同时异步逻辑也随之进行中,这里就是显示某一个特效,因为有个超时时间(避免一直显示),
        //等条件达成时,我们执行unitask的取消 也就是addBankerCoinTask.Cancel() 就可以触发
        // 异常逻辑 执行EndPlayAddBankerCoinAnim 这里就是隐藏特效显示。
        _=PlayAddBankerCoinAnim();
        //定时器 2秒后 执行unitask的取消逻辑,避免某些unitask一直等待某个条件一直等不到
        // 又或者是有个超时时间,当条件达成了主动取消等待直接走异常逻辑,执行动画的结束逻辑
        HotFix.Manager.TimerFolder.Timer.Register(2f, () =>
        {
            Debug.Log("发起取消补货");
            //注意 在你的mono对象销毁的时候或者确定退出的时候(可能会是隐藏取决于当时的业务)
            //需要手动调用一下addBankerCoinTask.Cancel(); 取消unitask任务
            addBankerCoinTask.Cancel();
        });
    }
    /// 播放一个特效,这里就是让该对象显示 注意try catch unitask的异常必须是
 /// try await 如果是_= 这种后台逻辑 是无法捕获的 
    private async UniTask PlayAddBankerCoinAnim()
    {
        addBankerCoinTask = new CancellationTokenSource();
        try  // 注意必须是try await的unitask才能捕获到异常
        {
            await PlayAddBankerCoinAnimImp(addBankerCoinTask.Token);
        }
        catch(OperationCanceledException e1)
        {
            EndPlayAddBankerCoinAnim();
        }
        catch(Exception e2)
        {
           EndPlayAddBankerCoinAnim();
        }
    }
    void EndPlayAddBankerCoinAnim()
    {
        bankerAddCoinObj?.SetActiveX(false);
    }
    
    async UniTask PlayAddBankerCoinAnimImp(CancellationToken cancel)
    {
        
        if (!GameBcMgr.Instance.IsAutoCostCoin)
        {
            bankerAddCoinObj?.SetActiveX(false);
            cancel.ThrowIfCancellationRequested();
            return;
        }
        bankerAddCoinObj?.SetActiveX(true);
        ///注意这里有一个等待超时60秒,并且传入了cancellationToken ,不传入则无法检测到异常
        await UniTask.WaitForSeconds(60f,cancellationToken:cancel);
     
        cancel.ThrowIfCancellationRequested();
        if (this == null || this.gameObject == null || !this.gameObject.activeInHierarchy)
        {
            cancel.ThrowIfCancellationRequested();
            return;
        }
        bankerAddCoinObj?.SetActiveX(false);
    }
} 

更多推荐