Unity——计时器功能实现
Unity计时器
Demo展示

介绍
游戏中有非常多的计时功能,比如:各种cd,以及需要延时调用的方法;
一般实现有一下几种方式:
1.手动计时
float persistTime = 10f
float startTime = Time.time;
if(Time.time - startTime > persistTime)
{
	Debug.Log("计时结束");
}
float curTime = 0;
curTime += Time.deltaTime;
if(curTime > persistTime)
{
    Debug.Log("计时结束");
}
2.协程
private float persistTime = 10f;
IEnumerator DelayFunc()
{
    yield return persistTime;
    Debug.Log("计时结束");
}
private void Start()
{
    StartCoroutine(DelayFunc());
}
3.Invoke回调
private void Start()
{
    Invoke("DelayFunc", persistTime);
}
计时器功能
计时是为了到特定的时间,执行某个功能或方法;
计时器(Timer):设计了计时暂停,计时重置,计时开始方法,计时中方法,计时结束方法,固定间隔调用方法,计时器可设置复用或单次;
计时管理器(TimerMa):负责倒计时,以及执行计时器方法;
代码:
using System;
using System.Collections.Generic;
using UnityEngine;
using Object = System.Object;
public class Timer
{
    public delegate void IntervalAct(Object args);
    //总时间和当前持续时间
    private float curtime = 0;
    private float totalTime = 0;
    //激活
    public bool isActive;
    //计时结束是否销毁
    public bool isDestroy;
    //是否暂停
    public bool isPause;
    //间隔事件和间隔事件——Dot
    private float intervalTime = 0;
    private float curInterval = 0;
    private IntervalAct onInterval;
    private Object args;
    //进入事件
    public Action onEnter;
    private bool isOnEnter = false;
    //持续事件
    public Action onStay;
    //退出事件
    public Action onEnd;
    public Timer(float totalTime, bool isDestroy = true, bool isPause = false)
    {
        curtime = 0;
        this.totalTime = totalTime;
        isActive = true;
        this.isDestroy = isDestroy;
        this.isPause = isPause;
        TimerMa.I.AddTimer(this);
    }
    public void Run()
    {
        //暂停计时
        if (isPause || !isActive)
            return;
        if (onEnter != null)
        {
            if (!isOnEnter)
            {
                isOnEnter = true;
                onEnter();
            }
        }
        //持续事件
        if (onStay != null)
            onStay();
        curtime += Time.deltaTime;
        //间隔事件
        if (onInterval != null)
        {
            curInterval += Time.deltaTime;
            if (curInterval > intervalTime)
            {
                onInterval(args);
                curInterval = 0;
            }
        }
        //计时结束
        if (curtime > totalTime)
        {
            curtime = 0;
            isActive = false;
            if (onEnd != null)
            {
                onEnd();
            }
        }
    }
    //设置间隔事件
    public void SetInterval(float interval, IntervalAct intervalFunc, Object args = null)
    {
        this.intervalTime = interval;
        onInterval = intervalFunc;
        curInterval = 0;
        this.args = args;
    }
    //重置计时器
    public void Reset()
    {
        curtime = 0;
        isActive = true;
        isPause = false;
        curInterval = 0;
        isOnEnter = false;
    }
    //获取剩余时间
    public float GetRemainTime()
    {
        return totalTime - curtime;
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TimerMa : MonoBehaviour
{
    #region 单例
    private static TimerMa instance;
    TimerMa() {}
    public static TimerMa I
    {
        get
        {
            if (instance == null)
                instance = new TimerMa();
            return instance;
        }
    }
    #endregion
    private List<Timer> timerList;
    private void Awake()
    {
        instance = this;
        timerList = new List<Timer>();
    }
    public void AddTimer(Timer t)
    {
        timerList.Add(t);
    }
    void Update()
    {
        for (int i = 0; i < timerList.Count;)
        {
            timerList[i].Run();
            //计时结束,且需要销毁
            if(!timerList[i].isActive && timerList[i].isDestroy)
                timerList.RemoveAt(i);
            else
                ++i;
        }
    }
}
测试计时器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Object = System.Object;
public class Test : MonoBehaviour
{
    public Text mText1;
    public Text mText2;
    private Timer timer;
    private int count = 0;
    void Start()
    {
        timer = new Timer(5f,false);
        timer.SetInterval(1f, OnInterval);
        timer.onEnter = OnStart;
        timer.onEnd = OnExit;
    }
    void Update()
    {
        Debug.Log(count);
        mText1.text = timer.GetRemainTime().ToString("f2");
        if (Input.GetKeyDown(KeyCode.A))
        {
            if (!timer.isPause)
            {
                timer.isPause = true;
                mText2.text = "暂停计时";
            }
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            if (timer.isPause)
            {
                timer.isPause = false;
                mText2.text = "取消暂停计时";
            }
        }
        if (Input.GetKeyDown(KeyCode.D))
        {
            timer.Reset();
            mText2.text = "重置计时";
        }
    }
    private void OnStart()
    {
        mText2.text = "开始计时";
    }
    private void OnExit()
    {
        mText2.text = "结束计时";
    }
    private void OnInterval(Object value)
    {
        count++;
        mText2.text = $"间隔事件调用{count}";
    }
}
Unity——计时器功能实现的更多相关文章
- JS中关于 一个关于计时器功能效果的实现
		optionSearch(); function optionSearch() { //定义一个清除计时器的变量 var timer = null; //自选标题区域 $("#optiona ... 
- iOS开发 - Swift使用GCD实现计时器功能
		前言 开发中,经常会用到定时执行网络请求.倒计时.计时器等功能,本篇文章介绍在iOS开发中,Swift怎样使用GCD实现这些功能. 执行一次 下面的代码将会在5秒后执行,且只执行一次. let tim ... 
- Window 8.1 计时器功能及图片切换
		<Canvas Margin="450,0" Width="795" Grid.Column="1"> <Image Ma ... 
- Unity基础功能:粒子特效(Shuriken)
		版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ... 
- Unity新功能|全息模拟器
		http://forum.china.unity3d.com/thread-21539-1-1.html 
- unity 计时器
		2017年1月3号,周二,晴. //设置时间 float tempTime = 5; void OnGUI(){ //设置显示 GUI.Label (new Rect(100,100,100,100) ... 
- 微信小程序canvas实现圆形计时器功能
		index.js import Canvas from '../../utils/canvas.js'Page({ ...Canvas.options, /** * 页面的初始数据 */ data: ... 
- 通过反射调用Unity编辑器提供的各种功能
		Unity编辑器功能丰富易上手,其实编辑器提供的大多数菜单操作,在代码里面都是能够找到对应接口的,但是这些接口都没有对我们开放,怎么办? 很简单,直接使用反射调用即可. 首先使用Reflector或I ... 
- C#  Unity依赖注入利用Attribute实现AOP功能
		使用场景? 很多时候, 我们定义一个功能, 当我们要对这个功能进行扩展的时候, 按照常规的思路, 我们一般都是利用OOP的思想, 在原有的功能上进行扩展. 那么有没有一种东西, 可以实现当我们需要扩展 ... 
随机推荐
- JS_DOM操作之常用事件
			1 - onload 事件:加载完成后立即执行 <!DOCTYPE html> <html lang="en"> <head> <meta ... 
- IKEv2协议关键知识点总结整理
			文章目录 @[toc] 1. IKEv2基本原理 2. IKEv2协议重点注意事项 2.1 情景一:==IKEv2协商密钥逻辑== ①密钥协商流程 ②函数调用关系 ③流程简述 2.2 情景二:==使用 ... 
- leetcode-H2O生成(多线程)
			现在有两种线程,氧 oxygen 和氢 hydrogen,你的目标是组织这两种线程来产生水分子. 存在一个屏障(barrier)使得每个线程必须等候直到一个完整水分子能够被产生出来. 氢和氧线程会被分 ... 
- 对Java的annotation(注解)的认识
			什么是java的annotation(注解) ? 注解的定义(annootation): public @interface TestAnnotation { } 上面的这种形式,便定义了注解是如何定 ... 
- win10 移动端 android 测试环境搭建
			一.移动端自动化测试的基础环境配置1:安装Java环境 关于安装Java环境以及相关环境变量的配置在我之前的博文分享中已有详细介绍,有需要的可以直接查找翻阅,这里就不再一一介绍. 二.移动端自动化测试 ... 
- appium和selenium不同与相同之处
			原文来自: https://www.cnblogs.com/zhengshuheng/p/6370398.html selenium是web端的自动化,appium是app端的自动化,它继承了webd ... 
- python with 线程锁
			import threading import time num = 0 # 全局变量多个线程可以读写,传递数据 mutex = threading.RLock() # 创建一个锁 class Myt ... 
- vm中安装win2012并安装hyper-V不支持嵌套
			在虚拟机中安装win2012,并安装hyper-v提示: 无法安装hyper-v:虚拟机监控程序已经在运行 找到虚拟机目录下,用文本编辑器打开该系统的虚拟机配置文件(.vmx后缀),在配置文件末尾增加 ... 
- Python实现一个简单三层神经网络的搭建并测试
			python实现一个简单三层神经网络的搭建(有代码) 废话不多说了,直接步入正题,一个完整的神经网络一般由三层构成:输入层,隐藏层(可以有多层)和输出层.本文所构建的神经网络隐藏层只有一层.一个神经网 ... 
- 深入浅出WPF-06.Binding(绑定)01
			Binding(绑定) 先上图,再解释 针对这个图,我们先来说说什么是Binding. Binding就是一个桥梁,建立在数据和UI之间的桥梁.既然是数据驱动,那么我们就把数据称之为"源&q ... 
