Unity中的异步编程【7】——在一个异步方法里播放了animation动画,取消任务时,如何停止动画播放

文章讨论了如何在Unity中使用异步方法控制动画播放,当用户取消任务时如何停止动画,提供了两种实现方式:一种是等待动画播放完成或取消信号,另一种是实时检查结束条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用一个异步方法来播放一个动画,正常情况是:动画播放结束时,异步方法宣告结束。那如果我提前取消这个异步任务,那在这个异步方法里面,我要怎么停止播放呢?!

一、播放animation动画的异步实现

  • 1、用play播放动画片段
  • 2、await一段时间,等动画播放结束
  • 3、用stop停止动画播放

二、两种实现方式

1 、纯多任务模式的实现

实现原理:
定义了两个结束的事件(或者Task):
(1)第一个是播放时长到点了
(2)第二个是用户取消了异步任务
(3)用whenAny等待

    /// <summary>
        /// 等待一个动画播放完毕
        /// 中间如果任务被取消,则停止播放动画
        /// </summary>
        /// <param name="Anim"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="speed"></param>
        /// <param name="ctk">任务取消标志</param>
        /// <returns></returns>

        public static async UniTask<bool> PlayAnim(Animation Anim, float startTime, float endTime, float speed, CancellationToken ctk)
        {
   
   
            Debug.Log($"当前Time.timeScale = {
     
     Time.timeScale}");
            float t = (endTime - startTime) * Time.timeScale; //考虑到动画时间倍率
            Debug.Log($"动画的时长为:{
     
     t}秒");
            Anim[Anim.clip.name].time = startTime;//跳过第几帧
            Anim[Anim.clip.name].speed = speed;
            Anim.Play(Anim.clip.name); //Play()

            //如果时间到点,结束,并停止动画
            Func<UniTask> timeFn = async () =>
            {
   
    
                await UniTask.Delay(TimeSpan.FromSeconds(t), cancellationToken: ctk);
                Anim.Stop();
            };

            //用户取消任务,结束,并停止动画
            Func<UniTask> cancelFn = async () =>
            {
   
   
                Debug.Log("开始执行cancelFn的循环:");
                while (true)
                {
   
   
                    Debug.Log($"ctk.IsCancellationRequested = {
     
     ctk.IsCancellationRequested}");
                    if (ctk.IsCancellationRequested)
                    {
   
   
                        Debug.Log($"任务取消:{
     
     ctk.IsCancellationRequested}");
                        Anim.Stop();
                        break;
                    };
                    
                    await UniTask.Yield();        //注意,这里不能随意加ctk,不然不能停,直接跳出了
                    //await UniTask.Yield(ctk);   
                }
                Debug.Log("结束cancelFn的循环");
            };

            //等待结束
            var idx = await UniTask.WhenAny(timeFn(), cancelFn()).AttachExternalCancellation(ctk);
            Debug.Log($"任务结束:结束方式为:{
     
     idx} 备注:0 = 动画播放结束,1 = 用户取消任务");
            return true;
        }

2 、手工启动一个循环,每帧检查结束条件

        /// <summary>
        /// 等待一个动画播放完毕
        /// 中间如果任务被取消,则停止播放动画
        /// 改进了结束的判断方式
        /// </summary>
        /// <param name="Anim"></param>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="speed"></param>
        /// <param name="ctk">任务取消标志</param>
        /// <returns></returns>

        public static async UniTask<bool> PlayAnim2(Animation Anim, float startTime, float endTime, float speed, CancellationToken ctk)
        {
   
   
            Debug.Log($"当前Time.timeScale = {
     
     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值