Unity开发小技巧(一)、计时器Timer

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

利用多线程的方式计时,缺点和第三种计时器一样

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("完成计时");
    }
}

运行结果:
在这里插入图片描述
大家可综合实际情况选择使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值