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——计时器功能实现的更多相关文章

  1. JS中关于 一个关于计时器功能效果的实现

    optionSearch(); function optionSearch() { //定义一个清除计时器的变量 var timer = null; //自选标题区域 $("#optiona ...

  2. iOS开发 - Swift使用GCD实现计时器功能

    前言 开发中,经常会用到定时执行网络请求.倒计时.计时器等功能,本篇文章介绍在iOS开发中,Swift怎样使用GCD实现这些功能. 执行一次 下面的代码将会在5秒后执行,且只执行一次. let tim ...

  3. Window 8.1 计时器功能及图片切换

    <Canvas Margin="450,0" Width="795" Grid.Column="1"> <Image Ma ...

  4. Unity基础功能:粒子特效(Shuriken)

    版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...

  5. Unity新功能|全息模拟器

    http://forum.china.unity3d.com/thread-21539-1-1.html

  6. unity 计时器

    2017年1月3号,周二,晴. //设置时间 float tempTime = 5; void OnGUI(){ //设置显示 GUI.Label (new Rect(100,100,100,100) ...

  7. 微信小程序canvas实现圆形计时器功能

    index.js import Canvas from '../../utils/canvas.js'Page({ ...Canvas.options, /** * 页面的初始数据 */ data: ...

  8. 通过反射调用Unity编辑器提供的各种功能

    Unity编辑器功能丰富易上手,其实编辑器提供的大多数菜单操作,在代码里面都是能够找到对应接口的,但是这些接口都没有对我们开放,怎么办? 很简单,直接使用反射调用即可. 首先使用Reflector或I ...

  9. C# Unity依赖注入利用Attribute实现AOP功能

    使用场景? 很多时候, 我们定义一个功能, 当我们要对这个功能进行扩展的时候, 按照常规的思路, 我们一般都是利用OOP的思想, 在原有的功能上进行扩展. 那么有没有一种东西, 可以实现当我们需要扩展 ...

随机推荐

  1. 痞子衡嵌入式:原来i.MXRT1xxx系列里也暗藏了Product ID寄存器

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1xxx系列里暗藏的Product ID寄存器. MCU 厂商在定义一个产品系列时,通常是会预先规划产品发展路线的(即会有一 ...

  2. String与基本类型,字符数组,字节数组的转换

    String与基本数据类型 * 基本数据 --->字符串(String) * 1.基本数据类型值 +"" --->最简单 * 2.使用包装类中的toString(参数类 ...

  3. String底层使用是char数组还是byte数组

    结论:jdk1.8及以前String底层使用是char[],1.9开始使用byte[] jdk1.8 jdk13

  4. Java空指针异常:java.lang.NullPointerException解决办法

    问题描述:运行maven项目抛出NullPointerException 空指针异常. 报空指针异常的原因有以下几种: 1字符串变量未初始化    例如:String x=null:对象x为null, ...

  5. 用java代码遍历excel文件并回显

    今天需要完成282个指标,分析后发现好多都是可复用的字段和方法,生成的dao类也是很多重复的代码,所以写下了简单的自动化遍历excel的test方法, excel业务逻辑如下,用了 HSSFSheet ...

  6. 【小程序】微信小程序iOS苹果报错“协议错误”

    遇到问题 目前正在开发一个小程序,然后苹果真机测试时发现无法授权并提示,errMsg:"request:fail 未能完成该操作.协议错误" 开发环境下测试没问题,安卓机真机测试没 ...

  7. Jvm调优理论篇

    Jvm实战调优 OOM(Out Of Memory) 内存溢出错误 ps:由于Java虚拟机有许多实现,本文主要阐述的是OpenJDK的HotSpot虚拟机,JDK版本是8. 一.首先要明白造成OOM ...

  8. Jmeter系列(12)- 上传接口压测

    step-1上传接口分析 上传接口源码分析:分析上传文件类型.有无大小限制.存放上传文件服务器 没有源码通过抓包工具,或者Chrome查看框架源代码 接口路径/uploadfile,接口请求POST, ...

  9. 链式调用+对象属性与遍历+this指向+caller/callee

    之前的作业: 提示: 在开发的时候尽量在函数内部将作用都给调用好,在外部就能够直接使用 链式调用: 正常这样是不行的,因为没有具体返回值:  return 具体的对象,这样的才是链式操作,jquery ...

  10. selenium下拉选择框处理

    HTML: (一)通过xpath层级标签定位 driver.find_element_by_xpath(".//*[@id='Resolution']/option[2]").cl ...