Unity3D实现计时器工具

系列文章目录

Unity工具



前言

大家好,我是★心疼你的一切★,不定时更新Unity开发技巧,觉得有用记得一键三连哦。
计时器的用处很多,所以记录一下


计时器的种类
1.倒计时
2.正计时
3.获取倒计时的时间
4.倒计时结束的回调

一、计时器的实现

代码如下:

using System.Collections;
using System.Collections.Generic;
using System.Timers;
using UnityEngine;
public delegate void CompleteEvent();
public delegate void UpdateEvent(float t);
public class TimerControl : MonoBehaviour
{
    UpdateEvent updateEvent;
    CompleteEvent onCompleted;
    bool isLog = true;//是否打印消息
    float timeTarget;   // 计时时间/
    float timeStart;    // 开始计时时间/
    float offsetTime;   // 计时偏差/
    bool isTimer;       // 是否开始计时/
    bool isDestory = true;     // 计时结束后是否销毁/
    bool isEnd;         // 计时是否结束/
    bool isIgnoreTimeScale = true;  // 是否忽略时间速率
    bool isRepeate;     //是否重复
    float now;          //当前时间 正计时
    float downNow;          //倒计时
    bool isDownNow = false;     //是否是倒计时

    // 是否使用游戏的真实时间 不依赖游戏的时间速度
    float TimeNow
    {
        get { return isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time; }
    }

    /// <summary>
    /// 创建计时器:名字  根据名字可以创建多个计时器对象
    /// </summary>
    public static TimerControl createTimer(string gobjName = "Timer")
    {
        GameObject g = new GameObject(gobjName);
        TimerControl timer = g.AddComponent<TimerControl>();
        return timer;
    }

    /// <summary>
    /// 开始计时
    /// </summary>
    /// <param name="time_">目标时间</param>
    /// <param name="isDownNow">是否是倒计时</param>
    /// <param name="onCompleted_">完成回调函数</param>
    /// <param name="update">计时器进程回调函数</param>
    /// <param name="isIgnoreTimeScale_">是否忽略时间倍数</param>
    /// <param name="isRepeate_">是否重复</param>
    /// <param name="isDestory_">完成后是否销毁</param>
    public void startTiming(float timeTarget, bool isDownNow = false,
        CompleteEvent onCompleted_ = null, UpdateEvent update = null,
        bool isIgnoreTimeScale = true, bool isRepeate = false, bool isDestory = true,
        float offsetTime = 0, bool isEnd = false, bool isTimer = true)
    {
        this.timeTarget = timeTarget;
        this.isIgnoreTimeScale = isIgnoreTimeScale;
        this.isRepeate = isRepeate;
        this.isDestory = isDestory;
        this.offsetTime = offsetTime;
        this.isEnd = isEnd;
        this.isTimer = isTimer;
        this.isDownNow = isDownNow;
        timeStart = TimeNow;

        if (onCompleted_ != null)
            onCompleted = onCompleted_;
        if (update != null)
            updateEvent = update;
    }

    void Update()
    {
        if (isTimer)
        {
            now = TimeNow - offsetTime - timeStart;
            downNow = timeTarget - now;
            if (updateEvent != null)
            {
                if (isDownNow)
                {
                    updateEvent(downNow);
                }
                else
                {
                    updateEvent(now);
                }
            }
            if (now > timeTarget)
            {
                if (onCompleted != null)
                    onCompleted();
                if (!isRepeate)
                    destory();
                else
                    reStartTimer();
            }
        }
    }

    /// <summary>
    /// 获取剩余时间
    /// </summary>
    /// <returns></returns>
    public float GetTimeNow()
    {
        return Mathf.Clamp(timeTarget - now, 0, timeTarget);
    }

    /// <summary>
    /// 计时结束
    /// </summary>
    public void destory()
    {
        isTimer = false;
        isEnd = true;
        if (isDestory)
            Destroy(gameObject);
    }

    float _pauseTime;
    /// <summary>
    /// 暂停计时
    /// </summary>
    public void pauseTimer()
    {
        if (isEnd)
        {
            if (isLog) Debug.LogWarning("计时已经结束!");
        }
        else
        {
            if (isTimer)
            {
                isTimer = false;
                _pauseTime = TimeNow;
            }
        }
    }

    /// <summary>
    /// 继续计时
    /// </summary>
    public void connitueTimer()
    {
        if (isEnd)
        {
            if (isLog) Debug.LogWarning("计时已经结束!请从新计时!");
        }
        else
        {
            if (!isTimer)
            {
                offsetTime += (TimeNow - _pauseTime);
                isTimer = true;
            }
        }
    }

    /// <summary>
    /// 重新计时
    /// </summary>
    public void reStartTimer()
    {
        timeStart = TimeNow;
        offsetTime = 0;
    }

    /// <summary>
    /// 更改目标时间
    /// </summary>
    /// <param name="time_"></param>
    public void changeTargetTime(float time_)
    {
        timeTarget = time_;
        timeStart = TimeNow;
    }


    /// <summary>
    /// 游戏暂停调用
    /// </summary>
    /// <param name="isPause_"></param>
    void OnApplicationPause(bool isPause_)
    {
        if (isPause_)
        {
            pauseTimer();
        }
        else
        {
            connitueTimer();
        }
    }
}

二、调用计时器的脚本

2-1 新建Test.cs脚本

2-2 倒计时代码如下

using UnityEngine;
using System.Collections;
using System;
using System.Timers;

public class Test : MonoBehaviour
{
    void Start()
    {
        // 创建倒计时器
        TimerControl timer = TimerControl.createTimer("GameTime");
        //开始计时
        timer.startTiming(10, true, OnComplete, OnProcess);
    }

    // 计时结束的回调
    void OnComplete()
    {
        Debug.Log("计时完成");
    }

    // 计时器的进程
    void OnProcess(float p)
    {
        Debug.Log(FormatTime(p));
    }

    /// <summary>
    /// 格式化时间
    /// </summary>
    /// <param name="seconds">秒</param>
    /// <returns></returns>
    public static string FormatTime(float seconds)
    {
        TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(seconds));
        string str = "";
        if (ts.Hours > 0)
        {
            str = ts.Hours.ToString("00") + ":" + ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00");
        }
        if (ts.Hours == 0 && ts.Minutes > 0)
        {
            str = ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00");
        }
        if (ts.Hours == 0 && ts.Minutes == 0)
        {
            str = "00:" + ts.Seconds.ToString("00");
        }
        return str;
    }
}

2-3 测试倒计时如下

没有录视频,可以自行测试看一下
在这里插入图片描述

三、正计时代码

代码如下:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Text_Zheng : MonoBehaviour
{
    void Start()
    {
        // 创建正计时器
        TimerControl timer = TimerControl.createTimer("GameTime");
        //开始计时
        timer.startTiming(10, false, OnComplete, OnProcess);
    }

    // 计时结束的回调
    void OnComplete()
    {
        Debug.Log("计时完成");
    }

    // 计时器的进程
    void OnProcess(float p)
    {
        Debug.Log(FormatTime(p));
    }

    /// <summary>
    /// 格式化时间
    /// </summary>
    /// <param name="seconds">秒</param>
    /// <returns></returns>
    public static string FormatTime(float seconds)
    {
        TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(seconds));
        string str = "";
        if (ts.Hours > 0)
        {
            str = ts.Hours.ToString("00") + ":" + ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00");
        }
        if (ts.Hours == 0 && ts.Minutes > 0)
        {
            str = ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00");
        }
        if (ts.Hours == 0 && ts.Minutes == 0)
        {
            str = "00:" + ts.Seconds.ToString("00");
        }
        return str;
    }
}

3-1 正计时效果

没有录视频,可以自行测试看一下
在这里插入图片描述

四、测试获取剩余的时间

4-1 代码如下

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Text_ShengYu : MonoBehaviour
{
    TimerControl timer;
    void Start()
    {
        // 创建正计时器
        timer = TimerControl.createTimer("GameTime");
        //开始计时
        timer.startTiming(10, true);
    }

    private void Update()
    {
        Debug.Log("剩余时间:"+timer.GetTimeNow());
    }
}

4-2 测试效果

在这里插入图片描述太长了,就截屏一个最后一点吧

五、测试暂停和继续

5-1 实现如下

代码如下

using UnityEngine;
using System.Collections;
using System;

public class Test_Stop : MonoBehaviour
{
    TimerControl timer;
    void Start()
    {
        // 创建倒计时器
        timer = TimerControl.createTimer("GameTime");
        //开始计时
        timer.startTiming(10, true, OnComplete, OnProcess);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            Debug.Log("暂停");
            timer.pauseTimer();//暂停
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            Debug.Log("继续");
            timer.connitueTimer();//继续
        }
        //if (Input.GetKeyDown(KeyCode.A))
        //{
        //    Debug.Log("重新计时");
        //    timer.reStartTimer();//重新计时
        //}
        //if (Input.GetKeyDown(KeyCode.D))
        //{
        //    Debug.Log("更改目标时间:20");
        //    timer.changeTargetTime(20);//更改目标时间
        //}
    }

    // 计时结束的回调
    void OnComplete()
    {
        Debug.Log("计时完成");
    }

    // 计时器的进程
    void OnProcess(float p)
    {
        Debug.Log(FormatTime(p));
    }

    /// <summary>
    /// 格式化时间
    /// </summary>
    /// <param name="seconds">秒</param>
    /// <returns></returns>
    public static string FormatTime(float seconds)
    {
        TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(seconds));
        string str = "";
        if (ts.Hours > 0)
        {
            str = ts.Hours.ToString("00") + ":" + ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00");
        }
        if (ts.Hours == 0 && ts.Minutes > 0)
        {
            str = ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00");
        }
        if (ts.Hours == 0 && ts.Minutes == 0)
        {
            str = "00:" + ts.Seconds.ToString("00");
        }
        return str;
    }
} 


5-2 结果如下

在这里插入图片描述

六、程序加速和不加速

6-1 实现如下

代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Test_SpeedUp : MonoBehaviour
{
    TimerControl timer;
    void Start()
    {
        Time.timeScale = 2;//游戏加速
        // 创建计时器
        timer = TimerControl.createTimer("GameTime");
        //开始计时
        timer.startTiming(60, true, OnComplete, OnProcess, false);
    }

    // 计时结束的回调
    void OnComplete()
    {
        Debug.Log("计时完成");
    }

    // 计时器的进程
    void OnProcess(float p)
    {
        Debug.Log(FormatTime(p));
    }

    /// <summary>
    /// 格式化时间
    /// </summary>
    /// <param name="seconds">秒</param>
    /// <returns></returns>
    public static string FormatTime(float seconds)
    {
        TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(seconds));
        string str = "";
        if (ts.Hours > 0)
        {
            str = ts.Hours.ToString("00") + ":" + ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00");
        }
        if (ts.Hours == 0 && ts.Minutes > 0)
        {
            str = ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00");
        }
        if (ts.Hours == 0 && ts.Minutes == 0)
        {
            str = "00:" + ts.Seconds.ToString("00");
        }
        return str;
    }
}

七、加速不加速的实现及结果

7-1 代码加速后的设置

在这里插入图片描述

7-2 加速结果如下

在这里插入图片描述

7-3 不加速的设置

不加速设置 默认就是1
在这里插入图片描述

7-4 不加速的结果

在这里插入图片描述

本次就这么多了,有需要会在添加


总结

本文参考地址:
https://itmonon.blog.csdn.net/article/details/124827131?spm=1001.2014.3001.5502
你的点赞就是对博主的支持,有问题记得留言
不定时更新Unity开发技巧,觉得有用记得一键三连哦。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 以下是一个简单的Unity一秒的计时器脚本示例: ```csharp using UnityEngine; public class Timer : MonoBehaviour { private float timer = 0.0f; private float seconds = 0.0f; void Update() { timer += Time.deltaTime; if (timer >= 1.0f) { seconds++; timer = 0.0f; Debug.Log("One second has passed!"); } } } ``` 在此示例中,我们使用Update函数来递增计时器变量,并检查计时器是否超过一秒。如果计时器已经超过一秒,我们将秒数加1,将计时器重置为0,并在控制台中输出消息。你可以根据自己的需求修改此示例来满足你的需求,例如在计时器达到某个特定秒数时执行特定的操作。 ### 回答2: Unity提供了用于计时的一秒钟的计时器功能。要创建一个一秒的计时器,你可以使用两种常用的方法:协程和InvokeRepeating函数。 使用协程的方法如下: 首先,在Unity中创建一个空物体来放置脚本。 在脚本中,需要声明一个浮点型变量来记录计时器时间,例如"float timer = 0f;"。 接下来,在Start()函数中启动协程函数,使用关键字"StartCoroutine()",并传入计时器协程函数的名称,例如"StartCoroutine(CountdownTimer());"。 定义一个协程函数CountdownTimer(),该函数使用关键字"yield return new WaitForSeconds(1);"来暂停1秒钟。 在CountdownTimer()函数内部,将计时器时间增加1秒钟,例如"timer += 1f;"。 你也可以在协程函数中添加任何你想要的其他功能,例如在计时器结束时触发事件或播放音效。 在Update()函数中,你可以使用计时器的值来检查是否达到指定的时间,然后执行相应的操作。 使用InvokeRepeating函数的方法如下: 在脚本的Start()函数中,使用关键字"InvokeRepeating()",并传入方法名称、延迟时间和重复时间间隔,例如"InvokeRepeating("TimerFunction", 0f, 1f);"。 定义一个方法TimerFunction(),该方法会在指定的时间间隔内被调用。 在TimerFunction()方法中,你可以执行任何你想要的操作,例如增加计时器时间和更新UI显示。 同样,在Update()函数中,你可以检查计时器的值是否达到指定的时间,并执行相应的操作。 以上就是使用Unity实现一秒钟计时器的两种常用方法,你可以根据自己的需求选择其中一种来实现。 ### 回答3: Unity中的计时器可以使用Coroutine和Time.deltaTime实现一秒的计时器。 首先,在Unity中创建一个新的C#脚本,可以命名为Timer.cs。在脚本中定义一个公共浮点型变量timeLeft,并初始化为1.0f。 然后,在Update函数中,使用timeLeft -= Time.deltaTime来逐帧减少计时器的数值。Time.deltaTime表示上一帧到当前帧的时间间隔,用于实现平滑的计时器。 接下来,在Update函数中使用if语句来检查计时器是否小于等于0。如果是,则说明一秒已经过去,可以触发相关逻辑,比如播放一个音效、生成一个物体等。在这个条件下,需要将timeLeft重新赋值为1.0f,以便下一次计时。 最后,在Unity中的游戏对象上添加Timer脚本,并通过调用StartCoroutine函数启动计时器。例如,在Start函数中添加StartCoroutine("Timer")。 完整的脚本示例: ```csharp using UnityEngine; public class Timer : MonoBehaviour { public float timeLeft = 1.0f; void Update() { timeLeft -= Time.deltaTime; if (timeLeft <= 0) { // 触发相关逻辑,比如播放一个音效、生成一个物体等 Debug.Log("一秒已经过去"); // 重新赋值为1.0f,启动下一次计时 timeLeft = 1.0f; } } } ``` 以上就是使用Coroutine和Time.deltaTime实现Unity中一秒的计时器的方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心疼你的一切

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值