Unity定时(延迟)管理器实现

前言

Unity中实现定时功能的方法有很多,比如协程、UpdateInvokeAsync等,可以说是五花八门,对于这类实现方法多、需求频繁的功能还是需要一个管理器来统一处理。

功能

下面列出了该管理器支持的功能,可以根据根据所列功能判断是否符合你的需求。
1.添加和移除并中断
2.自定义完成事件
3.延迟时间或帧数
4.指定执行次数
5.循环执行
6.是否受TimeScale影响

源码

代码中使用的MonoMgr是我实现的公共组件,方便外部代码调用MonoBehaviour,这部分可以根据自己的实际需求调整。其余部分开箱即用。
代码中有注释,没有太复杂的功能,就不过多解释了。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;public class TimerMgr : Singleton<TimerMgr>
{public delegate void CompleteEvent();class TimerData{public int id;public CompleteEvent onCompleted; //完成回调事件public float time;   // 所需时间或帧数public float targetTime;   // 目标时间(如果是帧数则无效)public bool isIgnoreTimeScale;  // 是否忽略时间速率public bool isLoop;     //是否重复public int executeCount;   //循环次数public bool isSecond;   //是否以秒为单位 否则为帧数public Coroutine coroutine; //标记协程}int timerId = 0;Dictionary<int, TimerData> timerDict = new Dictionary<int, TimerData>();List<int> tempRemoveTimer = new List<int>();public TimerMgr(){//绑定UpdateMonoMgr.Instance.AddUpdateListener(UpdateTime);}void UpdateTime(){for(int i = timerDict.Count - 1; i >= 0 ; i--){TimerData timeData = timerDict.ElementAt(i).Value;if (!timeData.isSecond){continue;}float nowTime = TimeNow(timeData.isIgnoreTimeScale);if (nowTime >= timeData.targetTime){timeData.onCompleted?.Invoke();timeData.executeCount -= 1;if (timeData.isLoop){timeData.targetTime = nowTime + timeData.time;}else{if(timeData.executeCount <= 0){tempRemoveTimer.Add(timeData.id);}else{timeData.targetTime = nowTime + timeData.time;}}}}for(int i = 0; i < tempRemoveTimer.Count; i++){RemoveTimer(tempRemoveTimer[i]);}tempRemoveTimer.Clear();}// 获取当前时间float TimeNow(bool isIgnoreTimeScale){return isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time;}/// <summary>/// 创建一个新的定时器(支持循环)/// </summary>/// <param name="time">延迟时间(秒)</param>/// <param name="onCompleted">结束回调</param>/// <param name="isLoop">是否循环,false则只执行一次</param>/// <param name="isSecond">秒/帧数</param>/// <param name="isIgnoreTimeScale">是否受TimeScale影响</param>/// <returns></returns>public int CreateNewTimer(float time, CompleteEvent onCompleted, bool isLoop = false, bool isSecond = true,bool isIgnoreTimeScale = false){timerId += 1;timerDict.Add(timerId, new TimerData(){id = timerId,onCompleted = onCompleted,time = time,targetTime = time + TimeNow(isIgnoreTimeScale),isIgnoreTimeScale = isIgnoreTimeScale,isLoop = isLoop,executeCount = 1,isSecond = isSecond});// 如果不是以秒为单位,则执行延迟帧数if (!isSecond){timerDict[timerId].coroutine = MonoMgr.Instance.StartCoroutine(DelayedExecution(timerDict[timerId]));}return timerId;}/// <summary>/// 创建一个新的定时器(支持执行次数)/// </summary>/// <param name="time">延迟时间(秒)</param>/// <param name="onCompleted">结束回调</param>/// <param name="count">执行次数</param>/// <param name="isSecond">秒/帧数</param>/// <param name="isIgnoreTimeScale">是否受TimeScale影响</param>/// <returns></returns>public int CreateNewCountTimer(float time, CompleteEvent onCompleted, int count, bool isSecond = true, bool isIgnoreTimeScale = false){timerId += 1;timerDict.Add(timerId, new TimerData(){id = timerId,onCompleted = onCompleted,time = time,targetTime = time + TimeNow(isIgnoreTimeScale),isIgnoreTimeScale = isIgnoreTimeScale,isLoop = false,executeCount = count,isSecond = isSecond});// 如果不是以秒为单位,则执行延迟帧数if (!isSecond){timerDict[timerId].coroutine = MonoMgr.Instance.StartCoroutine(DelayedExecution(timerDict[timerId]));}return timerId;}/// <summary>/// 移除指定定时器/// </summary>public void RemoveTimer(int id){if (timerDict.ContainsKey(id)){TimerData data = timerDict[id];if (!data.isSecond){MonoMgr.Instance.StopCoroutine(data.coroutine);}data = null;timerDict.Remove(id);}}/// <summary>/// 清除所有定时器/// </summary>public void RemoveAllTimer(){for (int i = timerDict.Count - 1; i >= 0; i--){int id = timerDict.ElementAt(i).Key;RemoveTimer(id);}}IEnumerator DelayedExecution(TimerData data){// 等待指定的帧数for (int i = 0; i < data.time; i++){yield return null; // 等待下一帧}// 执行动作data.onCompleted?.Invoke();data.executeCount -= 1;if (data.isLoop){// 防止完成事件中移除了定时器,不判断会导致依然执行协程if(data != null && timerDict.ContainsKey(data.id)){data.coroutine = MonoMgr.Instance.StartCoroutine(DelayedExecution(data));}}else{if(data.executeCount <= 0){RemoveTimer(data.id);}else{if (data != null && timerDict.ContainsKey(data.id)){data.coroutine = MonoMgr.Instance.StartCoroutine(DelayedExecution(data));}}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/31845.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tron-passwd写入提权

troneasy敏感信息收集、Brainfuck解密、替换密码、ssh利用、passwd提权机发现 **后续需要虚拟机的私信我&#xff0c;我会打包进行文章发布链接&#xff0c;请持续关注&#xff01;&#xff01;&#xff01;** 主机发现 netdiscover -i eth0 -r 192.168.44.0/24端口服务 nm…

注解详解系列 - @Profile:基于环境的配置切换

注解简介 在今天的注解详解系列中&#xff0c;我们将探讨Profile注解。Profile是Spring框架中的一个重要注解&#xff0c;用于根据不同的环境配置有选择性地启用或禁用特定的bean。通过Profile注解&#xff0c;可以方便地在开发、测试、生产等不同环境中切换配置。 注解定义 …

速盾:cdn加速什么好?

CDN加速是一种通过使用内容分发网络&#xff08;Content Delivery Network&#xff09;来提高网站速度的技术。在了解CDN加速的好处之前&#xff0c;首先需要明白什么是CDN。CDN是一种分布在全球不同地理位置的服务器网络&#xff0c;用于存储和交付网站的静态和动态内容。当用…

AI语言文字工具类API实现自动化的写作

热门实用的AI语言文字工具类API是当今开发者们追逐的宝藏。这些API利用先进的人工智能和自然语言处理技术&#xff0c;为开发者提供了一系列实用而强大的语言文字处理能力。这些API包括了文本翻译、情感分析、智能写作、关键词提取、语言检测等功能&#xff0c;使得开发者能够轻…

timescaledb:创建real-time aggregate

创建hypertable【chz_a】 create table chz_a (time timestamp,device_id int8, value double precision,primary key (time) ); SELECT create_hypertable(chz_a, by_range(time) );往表里面写入数据 # 当天的数据 insert into chz_a (time, device_id, value) values (now(…

【Python爬虫】爬取名人名言页面并进行简单的数据清洗(入门级)

目录 资源链接 一、网站选择 二、数据爬取要求 三、数据清洗要求 四、实现代码 1.数据采集 2.数据清洗 资源链接 下面有笔者所放的源码下载链接&#xff0c;读者可自行下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1YmTdlnbSJLvLrrx92zz6Qg 提取码&…

Python酷库之旅-第三方库openpyxl(03)

目录 一、 openpyxl库的由来 1、背景 2、起源 3、发展 4、特点 4-1、支持.xlsx格式 4-2、读写Excel文件 4-3、操作单元格 4-4、创建和修改工作表 4-5、样式设置 4-6、图表和公式 4-7、支持数字和日期格式 二、openpyxl库的优缺点 1、优点 1-1、支持现代Excel格式…

DDA直线算法

理论部分 假设给定直线段的起点坐标 ( x 0 , y 0 ) (x_0,y_0) (x0​,y0​)和终点坐标 ( x 1 , y 1 ) (x_1,y_1) (x1​,y1​),则该直线的直线方程为: y = k x + b y=kx + b y=kx+b 其中 k = y 1 − y 2 x 2 − x 1 , b = y 0 − k x 0 k=\frac{y_1-y_2}{x_2-x_1},b=y_0-kx_0 k…

tdlib自定义Telegram客户端电报客户端

之前做过多个电报机器人 最近闲来无事,顺手了解了下tdlib,打算使用dart做一个pc和移动端的tg客户端,顺便解决官方无法下载某些视频图片文件的问题. 前期踩了不少坑,花了3天时间完成了pc端的基本功能 效果展示

P5714 【深基3.例7】肥胖问题

1. 题目链接 https://www.luogu.com.cn/problem/P5714 P5714 【深基3.例7】肥胖问题 2. 题目描述 题目描述&#xff1a;BMI计算:m / (h * h)&#xff0c;m是体重(kg)&#xff0c;h是身高(m) 小于18.5&#xff1a;体重国轻&#xff0c;Underweight 小于等于18.5且小于24&#…

电脑文件夹怎么加密?文件夹加密的5种方法

在数字化时代&#xff0c;信息安全显得尤为重要。对于个人电脑用户来说&#xff0c;文件夹加密是一种有效保护隐私和数据安全的方法。本文将介绍五种文件夹加密的方法&#xff0c;帮助您更好地保护自己的重要文件。 如何设置文件夹密码方法一&#xff1a;利用Windows系统自带的…

shardingsphere调优日记

文章目录 一、总括二、连接数调优二、CPU线程的利用率三、服务器内存的利用率 一、总括 调优的几个方面 连接数调优&#xff0c;包含shardingsphere和mysql的连接数。shardingsphere的globle.yaml中线程调优。&#xff08;充分利用CPU&#xff09;shardingsphere中的内存调优…

节能减排如何替电子行业巨头降低成本

尖端科技与环境之间的矛盾&#xff0c;已经不再是科幻小说家笔下的虚构。 先进芯片制造从熔化硅开始&#xff0c;到使用大功率激光进行光刻&#xff0c;再到创造和维护真空状态&#xff0c;以及持续清洁工作&#xff0c;每一个环节都需要大量的电力支持。据统计&#xff0c;半…

体验一下 Claude 3.5 Sonnet

体验一下 Claude 3.5 Sonnet 0. 引言1. Artifacts - 使用 Claude 的新方式2. 体验一下 Claude 3.5 Sonnet 0. 引言 2024年6月21日&#xff0c;Anthropic 推出 Claude 3.5 Sonnet&#xff0c;这是即将推出的 Claude 3.5 型号系列中的第一个版本。 Claude 3.5 Sonnet 提高了行业…

南昌代理记账报税的详细说明

随着社会经济的发展和企业运营的需要&#xff0c;越来越多的企业开始寻找专业的会计服务&#xff0c;我们特别为您提供南昌代理记账报税的相关信息。 https://www.9733.cn/news/detail/166.html 代理记账的主要功能 1、代理记账为企业提供专业化的财务咨询服务。 2、及时准确…

前端调用api发请求常用的请求头content- type的类型和常用场景

Content-Type 是一个非常重要的HTTP头&#xff0c;它定义了发送给服务器或客户端的数据的MIME类型。这对于服务器和客户端正确解析和处理数据至关重要。下面是一些常见的 Content-Type 值及其用途和区别。 常见的 Content-Type 值 text/plain • 用途: 纯文本&#xff0c;无格…

信息检索(43):SPLADE: Sparse Lexical and Expansion Model for First Stage Ranking

SPLADE: Sparse Lexical and Expansion Model for First Stage Ranking 摘要1 引言2 相关工作3 方法3.1 SparTerm3.2 SPLADE&#xff1a;稀疏词汇和扩展模型 4 实验5 结论 发布时间&#xff08;2021&#xff09; 标题&#xff1a;稀疏词汇 扩展模型 摘要 稀疏的优点&#xf…

实现可扩展的电商返利平台:技术选型与挑战

实现可扩展的电商返利平台&#xff1a;技术选型与挑战 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在当今数字化和电商兴盛的时代&#xff0c;返利平台成为…

[程序员] 外企工作的英语重要性

作为一名程序员&#xff0c;英语的必备性是不可或缺&#xff0c;尤其是在一个外企&#xff01; 因为在工作中&#xff0c;英语是非常重要的一门基础技术&#xff0c;所有的产品代码/第三方开源软件都是英语书写&#xff0c;包括代码逻辑&#xff0c;变量/函数/类定义&#xff…

Python酷库之旅-第三方库openpyxl(02)

目录 一、 openpyxl库的由来 1、背景 2、起源 3、发展 4、特点 4-1、支持.xlsx格式 4-2、读写Excel文件 4-3、操作单元格 4-4、创建和修改工作表 4-5、样式设置 4-6、图表和公式 4-7、支持数字和日期格式 二、openpyxl库的优缺点 1、优点 1-1、支持现代Excel格式…