1.第一种计时器Time.deltaTime
Time.deltaTime为游戏每帧执行的时间,该方法一般用加法来计时,原理是利用nity中Update方法的每帧执行的时间,按钮按下后不断累加,大于计时时间时关闭,可根据实际使用情况进行加减,以下给出加法操作。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TimeTest : MonoBehaviour
{
float totalTime = 3;
float timer = 0;
bool isStartTimer = false;
public Button button;
// Start is called before the first frame update
void Start()
{
button.onClick.AddListener(OnClickBtn);
}
private void OnClickBtn()
{
isStartTimer = true;
Debug.Log("开始计时");
}
// Update is called once per frame
void Update()
{
if (isStartTimer)
{
timer += Time.deltaTime;
Debug.Log("计时中:"+(int)timer);
if(timer >= totalTime)
{
Debug.Log("结束计时:"+(int)timer);
isStartTimer = false;
timer = 0;
}
}
}
}
演示结果:
2.第二种计时器Time.time
Time.time为从游戏运行开始到现在的时间,该方法一般用作减法计时,原理是先记录一下按钮按下时的那一瞬间的时间,再用当前时间减去记录的时间,大于计时时间时关闭,也是依靠Unity中Update方法的帧执行,可根据实际使用情况进行加减,以下给出减法操作。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TimeTest2 : MonoBehaviour
{
float totalTime = 3;
float recordTime = 0;
public Button button;
bool isStartTimer = false;
// Start is called before the first frame update
void Start()
{
button.onClick.AddListener(OnClickBtn);
}
private void OnClickBtn()
{
Debug.Log("timer2开始计时");
recordTime = Time.time;
isStartTimer = true;
}
// Update is called once per frame
void Update()
{
if (isStartTimer)
{
Debug.Log("timer2计时中:" + (int)(Time.time - recordTime));
if(Time.time - recordTime >= totalTime)
{
Debug.Log("timer2结束计时:" + (int)(Time.time - recordTime));
isStartTimer = false;
}
}
}
}
演示结果:
3.第三种计时器timer
该计时器为C#中依靠线程执行的计时器。我自己又封装了一下,大家可参考如下代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyTimer
{
System.Timers.Timer timer;
public MyTimer()
{
timer = new System.Timers.Timer();
timer.Interval = 2000;
timer.Elapsed += FinishTimer;
}
public MyTimer(double time)
{
timer = new System.Timers.Timer();
timer.Interval = time;
timer.Elapsed += FinishTimer;
}
public void Start()
{
Debug.Log("开始");
timer.Start();
}
public void Stop()
{
timer.Stop();
}
public void FinishTimer(object sender, System.Timers.ElapsedEventArgs e)
{
Debug.Log(sender.ToString());
Debug.Log("timer3:完成计时:" + e.SignalTime.ToLocalTime());
timer.Stop();
}
}
演示结果:
区别
第一种和第二种需要放在主线程(Update方法)中执行,第三种为另外分一个线程执行起到了分担主线程的作用。但各有各的好处,在第三种方法中不能直接调用GameObject,Instantiate,(UI中)Text等对象或方法,如果涉及文本框数字的实时显示,推荐使用一,二种方法;如果只是需要计时后调用一次的,如按钮的长按等,可设置bool开关并结合主线程控制,用来分担主线程压力。在profile性能分析器中可明显的观测到第一种方法和第二种方法有在计时的时候有明显的波峰出现,而第三种方法只在按钮点击的瞬间有明显的波峰显示,大家可结合性能分析profile来观察,得出结论。
4.第四种计时器Invoke
Unity中Mono提供了Invoke(“methodName”,time)方法,其作用是多长时间执行该方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InvokeTimer : MonoBehaviour
{
public float time = 3.5f;
private int index = 0;
// Start is called before the first frame update
void Start()
{
Timer(time);
}
void StartTimer()
{
index++;
if (index > time)
{
Debug.Log(time);
Debug.Log("完成计时");
return;
}
Debug.Log(index);
}
private void Timer(float time)
{
if (time < 1)
{
Invoke("StartTimer", time);
return;
}
for (int i = 1; i < time; i++)
{
Invoke("StartTimer", i);
}
Invoke("StartTimer", time);
}
}
运行结果:
5.第五种计时器IEnumerator
利用协程的yield return new WaitForSeconds(float time),此方法既可以不占用主线程,又可以操控unity中的控件,如Text,GameObject等类。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class IEnumeratorTimer : MonoBehaviour
{
public float time = 5.43f;
public Text text;
// Start is called before the first frame update
void Start()
{
StartCoroutine(Timer(time));
}
IEnumerator Timer(float time)
{
for (int i = 1; i < time; i++)
{
yield return new WaitForSeconds(1);
Debug.Log(i);
text.text = i.ToString();
}
float remainTime = time - (int)time;
if(remainTime != 0)
{
yield return new WaitForSeconds(remainTime);
text.text = time.ToString();
Debug.Log(time);
Debug.Log("完成计时");
}
}
}
运行效果:
6.第六种计时器Thread
利用多线程的方式计时,缺点和第三种计时器一样文章来源:https://www.toymoban.com/news/detail-456499.html
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.Events;
public class ThreadTimer : MonoBehaviour
{
public float time = 7.52f;
// Start is called before the first frame update
void Start()
{
Thread thread = new Thread(StartTimer);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
private void StartTimer()
{
Timer(time, FinishTimer);
}
private void Timer(float time,UnityAction unity)
{
int remainTime = 0;//剩余时间
if (time < 1)
{
remainTime = (int)(time * 1000);
Thread.Sleep(remainTime);
Debug.Log(time);
return;
}
int count = (int)time;
remainTime = (int)((time - count) * 1000);
for (int i = 1; i < time; i++)
{
Thread.Sleep(1000);
Debug.Log(i);
}
Thread.Sleep(remainTime);
Debug.Log(time);
unity();
}
public void FinishTimer()
{
Debug.Log("完成计时");
}
}
运行结果:
大家可综合实际情况选择使用。文章来源地址https://www.toymoban.com/news/detail-456499.html
到了这里,关于Unity开发小技巧(一)、计时器Timer的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!