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

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

  • 8
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity开发中,有一些小技巧可以提高效率和方便开发。以下是一些常用的Unity开发技巧: 1. 锁定角度和移动对象:在旋转对象时按住Ctrl/Cmd键可以锁定角度,同样的方法也适用于移动对象。要修改锁定的默认值,可以到Edit->SnapSettings进行修改。 2. 对齐锁定技巧:当移动对象时,按住V键可以启用节点锁定,可以将两个点简单对齐,对于关卡对象排列有帮助。 3. 直接开启说明文件:在组件选单内点击蓝色的问号图标,可以直接打开说明文件。 4. 在Play模式下修改数值:如果在Play模式下调整数值后发现不合适,可以点击组件列表右上方的小齿轮,然后选择CopyComponent将组件复制一份,在退出Play模式后再点击小齿轮选择PasteComponent将复制的组件粘贴回去。 5. 使用Layers按钮管理显示或隐藏对象:使用Layers按钮可以管理显示或隐藏对象。例如,可以将一些只在编辑初期使用的坐标对象归类到一个Layer,当要隐藏这些对象时,只需点击Layers按钮,然后将该图层右边的眼睛图标取消勾选即可。 6. 在Profiler中切换图表显示:在Profiler中,可以点击Drawcalls、Scripts、Rendering、VSync等名称左边的小方块来切换是否显示相应图表。 7. 调整Playmode tint颜色:初学者在Play模式下修改东西后,可能在停止播放后发现所有的修改都恢复到调整前。为了避免这种困扰,可以在Preferences设置中的Colours/Colors调整Playmode tint颜色,这样你就可以很容易地分辨是否在播放模式。 这些小技巧可以帮助开发者更高效地使用Unity进行开发和调试。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Unity 开发的十个实用小技巧](https://blog.csdn.net/weixin_46052359/article/details/115072925)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值