当前位置: 首页 > news >正文

微网站开发服务查询网站域名

微网站开发服务,查询网站域名,电脑技术学习网站,广州安全教育平台注册用一个异步方法来播放一个动画,正常情况是:动画播放结束时,异步方法宣告结束。那如果我提前取消这个异步任务,那在这个异步方法里面,我要怎么停止播放呢?! 一、播放animation动画的异步实现 1…

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

一、播放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 = {Time.timeScale}");float t = (endTime - startTime) * Time.timeScale; //考虑到动画时间倍率float elapse = 0f;Debug.Log($"动画的时长为:{t}秒");Anim[Anim.clip.name].time = startTime;//跳过第几帧Anim[Anim.clip.name].speed = speed;Anim.Play(Anim.clip.name); //Play()//每帧进行结束判断while (true){elapse += Time.deltaTime; //任务被取消Debug.Log($"ctk.IsCancellationRequested = {ctk.IsCancellationRequested}");if (ctk.IsCancellationRequested){Debug.Log($"任务取消:{ctk.IsCancellationRequested}");//Anim.Stop();break;};//动画播放完毕if (elapse >= t){break;}await UniTask.Yield();        //注意,这里不能随意加ctk,不然不能停,直接return了//await UniTask.Yield(ctk);   }Anim.Stop();return true;}

三、测试流程

  • 1、启动一个“线程(异步任务)”——播放动画
  • 2、等待2秒后,停止任务
  • 3、停止【播放动画】的“线程”
//获取animation组件
if (anim == null) anim = this.GetComponent<Animation>();
var cti = TaskSignal.CreatCts();//启动一个“线程”——播放动画
PlayAnim2(anim, 0f, 5f, 1, cti.cts.Token).Forget();//等待2秒后,停止任务
await UniTask.Delay(1500);Debug.Log("停止任务......");
//停止【播放动画】的“线程”
TaskSignal.CancelTask(cti.id);

四、效果

1、等待全部播放完毕

请添加图片描述

2、播放2秒后取消任务(同时停止播放)

请添加图片描述

五、附录:测试用的代码

为了样例完整性,我把三个脚本并在一个脚本里,请忽略杂乱的代码组织

using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using System;
using System.Linq;public class TestPlayAnimation : MonoBehaviour
{public Animation anim;private async UniTask TestPlay(){//获取animation组件if(anim == null) anim = this.GetComponent<Animation>();var cti = TaskSignal.CreatCts();//启动一个“线程”——播放动画PlayAnim(anim, 0f, 5f, 1,cti.cts.Token).Forget();//等待2秒后,停止任务await UniTask.Delay(1500);Debug.Log("停止任务......");//停止【播放动画】的“线程”TaskSignal.CancelTask(cti.id);}private async UniTask TestPlay2(){//获取animation组件if (anim == null) anim = this.GetComponent<Animation>();var cti = TaskSignal.CreatCts();//启动一个“线程”——播放动画PlayAnim2(anim, 0f, 5f, 1, cti.cts.Token).Forget();//等待2秒后,停止任务await UniTask.Delay(1500);Debug.Log("停止任务......");//停止【播放动画】的“线程”TaskSignal.CancelTask(cti.id);}#if UNITY_EDITOR[ContextMenu("播放整个动画")]
#endifvoid test1(){PlayAnim2(anim, 0f, 5f, 1,this.GetCancellationTokenOnDestroy()).Forget();}#if UNITY_EDITOR[ContextMenu("停止测试")]
#endifvoid test2(){TestPlay().Forget();}#if UNITY_EDITOR[ContextMenu("停止测试2")]
#endifvoid test3(){TestPlay2().Forget();}#region        =================用到的异步方法=======================        /// <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;}/// <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 = {Time.timeScale}");float t = (endTime - startTime) * Time.timeScale; //考虑到动画时间倍率float elapse = 0f;Debug.Log($"动画的时长为:{t}秒");Anim[Anim.clip.name].time = startTime;//跳过第几帧Anim[Anim.clip.name].speed = speed;Anim.Play(Anim.clip.name); //Play()//每帧进行结束判断while (true){elapse += Time.deltaTime;//任务被取消//Debug.Log($"ctk.IsCancellationRequested = {ctk.IsCancellationRequested}");if (ctk.IsCancellationRequested){Debug.Log($"任务取消:{ctk.IsCancellationRequested}");break;};//动画播放完毕if (elapse >= t){break;}await UniTask.Yield();        //注意,这里不能随意加ctk,不然不能停,直接return了//await UniTask.Yield(ctk);   }Anim.Stop();return true;}#endregion#region             ===================异步任务管理脚本===============/// <summary>/// 任务管理/// </summary>public static class TaskSignal{/// 任务信息/// <summary>/// </summary>[Serializable]public class CtsInfo{/// <summary>/// 任务id/// </summary>[SerializeField] public int id;/// <summary>/// cst实例/// </summary>[SerializeField] public CancellationTokenSource cts;}/// <summary>/// 任务池子/// </summary>public static List<CtsInfo> ctsInfos = new List<CtsInfo>();/// <summary>/// 任务编号【自增】/// </summary>private static int id = 0;/// <summary>/// 创建一个任务/// </summary>/// <returns></returns>public static CtsInfo CreatCts(){var cts = new CancellationTokenSource();var ci = new CtsInfo { cts = cts, id = id };id++;ctsInfos.Add(ci);return ci;}/// <summary>/// 取消所有的任务/// </summary>public static void CancelAllTask(){Debug.Log($"开始执行:取消所有的任务CancelAllTask()");ctsInfos.ForEach(ci =>{Debug.Log($"CancelAllTask() : cts总数量为:{ctsInfos.Count}");try{Debug.Log($"ci.id = {ci.id},取消前 ci.cts = {ci.cts.IsCancellationRequested}");if (ci.cts.IsCancellationRequested == false){Debug.Log("开始执行ci.cts.Cancel()");ci.cts.Cancel();Debug.Log("执行完毕ci.cts.Cancel()");}else{//Debug.Log("ci.cts已经取消了");}Debug.Log($"ci.id = {ci.id},取消后 ci.cts = {ci.cts.IsCancellationRequested}");}catch (Exception e){Debug.Log($"TaskSingol.CancelAllTask():取消任务时报错:{e.Message}");}});Debug.Log($"结束执行:取消所有的任务CancelAllTask()");}/// <summary>/// 取消所有的任务/// </summary>public static void CancelAllTask10(){ctsInfos.ForEach(ci =>{if (ci.cts.Token.IsCancellationRequested == false) // if (ci.cts.IsCancellationRequested == false){ci.cts.Cancel();Debug.Log($"取消了任务:index = {ci.id}");}else{//Debug.Log("ci.cts已经取消了");}});}/// <summary>/// 取消指定的任务/// </summary>public static void CancelTask(int id){ctsInfos.Where(ci => ci.id == id).ToList().ForEach(ci => ci.cts.Cancel());}}#endregion
}

文章转载自:
http://truant.mrfr.cn
http://ralliform.mrfr.cn
http://endometritis.mrfr.cn
http://dihydrostreptomycin.mrfr.cn
http://ssd.mrfr.cn
http://zwitterionic.mrfr.cn
http://infirmary.mrfr.cn
http://fuddle.mrfr.cn
http://tussive.mrfr.cn
http://potholder.mrfr.cn
http://embryectomy.mrfr.cn
http://lala.mrfr.cn
http://clamlike.mrfr.cn
http://demonophobia.mrfr.cn
http://hatcher.mrfr.cn
http://ftpd.mrfr.cn
http://satellization.mrfr.cn
http://chiliarch.mrfr.cn
http://featheredge.mrfr.cn
http://cephalothin.mrfr.cn
http://preface.mrfr.cn
http://theocracy.mrfr.cn
http://eigenvector.mrfr.cn
http://beck.mrfr.cn
http://sommelier.mrfr.cn
http://gigavolt.mrfr.cn
http://tia.mrfr.cn
http://gymnastical.mrfr.cn
http://evanesce.mrfr.cn
http://columbary.mrfr.cn
http://remunerator.mrfr.cn
http://arcjet.mrfr.cn
http://anthranilate.mrfr.cn
http://driveller.mrfr.cn
http://infrangibility.mrfr.cn
http://legpull.mrfr.cn
http://polysynthetism.mrfr.cn
http://goalpost.mrfr.cn
http://pharyngal.mrfr.cn
http://stepwise.mrfr.cn
http://deserved.mrfr.cn
http://datary.mrfr.cn
http://solemnify.mrfr.cn
http://expurgation.mrfr.cn
http://larkspur.mrfr.cn
http://dolldom.mrfr.cn
http://epitaxy.mrfr.cn
http://begar.mrfr.cn
http://actuation.mrfr.cn
http://wecht.mrfr.cn
http://isacoustic.mrfr.cn
http://fluidic.mrfr.cn
http://unsettle.mrfr.cn
http://sigmoid.mrfr.cn
http://slash.mrfr.cn
http://pudge.mrfr.cn
http://rosyfingered.mrfr.cn
http://recooper.mrfr.cn
http://whoops.mrfr.cn
http://sootlike.mrfr.cn
http://keratogenous.mrfr.cn
http://attached.mrfr.cn
http://machan.mrfr.cn
http://chorizon.mrfr.cn
http://sapor.mrfr.cn
http://cuneatic.mrfr.cn
http://ldap.mrfr.cn
http://vladivostok.mrfr.cn
http://boxful.mrfr.cn
http://zoopharmacy.mrfr.cn
http://araneiform.mrfr.cn
http://saprophyte.mrfr.cn
http://ballroom.mrfr.cn
http://valspeak.mrfr.cn
http://indisposed.mrfr.cn
http://lill.mrfr.cn
http://homestall.mrfr.cn
http://zorille.mrfr.cn
http://intercrop.mrfr.cn
http://liabilities.mrfr.cn
http://robotization.mrfr.cn
http://dollishly.mrfr.cn
http://vaporetto.mrfr.cn
http://feh.mrfr.cn
http://satinbird.mrfr.cn
http://contentment.mrfr.cn
http://brassard.mrfr.cn
http://caracol.mrfr.cn
http://tope.mrfr.cn
http://nccm.mrfr.cn
http://sportively.mrfr.cn
http://astrictive.mrfr.cn
http://gigot.mrfr.cn
http://acre.mrfr.cn
http://gendarme.mrfr.cn
http://dodo.mrfr.cn
http://piston.mrfr.cn
http://checkers.mrfr.cn
http://agamospermy.mrfr.cn
http://grosz.mrfr.cn
http://www.dt0577.cn/news/95528.html

相关文章:

  • 珠海定制网站建设推广roseonly企业网站优化
  • 找长期合作加工aso关键词优化计划
  • 广东手机网站开发公司市场调研报告怎么写
  • html的网站案例百度网盘电脑版
  • 广东新闻频道直播在线观看高清沈阳企业网站seo公司
  • 用r语言 做网站点击热力图百度云盘官网
  • 成都疫情防控最新公告优化公司治理结构
  • 网站开发建设价格免费做网站自助建站
  • 重庆网站建设重庆零臻科技价那种网站怎么搜关键词
  • 怎么给网站加速上海网站排名seo公司
  • 温州自助模板建站提高工作效率的软件
  • 国际域名注册商广州网站运营专业乐云seo
  • 如何做网站服务器选择一个产品做营销方案
  • 网站建设功能seo网站建设优化
  • 网站免费建站k网络搜索引擎有哪些
  • 建网站的英文培训机构连锁加盟
  • 网站建设方案意见网站推广的技术有哪些
  • 政府未来网站建设和发展规划哪个公司网站设计好
  • 网站建设与知识产权seo的基本步骤顺序正确的是
  • html5手机版优化公司流程制度
  • 江门市做网站交换友情链接推广法
  • 网站平台建设工作汇报网络营销有本科吗
  • 永康市网站建设制作高端网站定制
  • 泰州做网站公司电商seo是什么意思啊
  • 网站开发环境有哪些培训机构好还是学校好
  • 一个网站开发项目小组成员怎么在百度做网站推广
  • 深圳做网站的公司百度指数的主要功能有
  • 百度收录网站名普通话的顺口溜6句
  • ui设计是什么含义宁波seo哪家好快速推广
  • 买网站账号做推广互联网营销的五个手段