前言
协程任务能够作为定时器使用,但存在一个问题:必须将其置于脚本中。然而,我们游戏的逻辑大部分都在 C# 代码中,因此需要封装一个不依赖于脚本的定时器。
一、定时器
使用协程程序来实现定时器功能,可以通过向 WaitTime() 方法传递定时时间和时间结束后的回调方法来处理定时事件。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class WaitTimeManager
{
private static TaskBehaviour m_Task;
static WaitTimeManager()
{
GameObject go = new GameObject("#WaitTimeManager#");
GameObject.DontDestroyOnLoad(go);
m_Task = go.AddComponent<TaskBehaviour>();
}
//等待
static public Coroutine WaitTime(float time,UnityAction callback)
{
return m_Task.StartCoroutine(Coroutine(time,callback));
}
//取消等待
static public void CancelWait(ref Coroutine coroutine)
{
if(coroutine != null) {
m_Task.StopCoroutine(coroutine);
coroutine = null;
}
}
static IEnumerator Coroutine(float time,UnityAction callback){
yield return new WaitForSeconds(time);
if(callback != null) {
callback();
}
}
//内部类
class TaskBehaviour : MonoBehaviour{}
}
调用方法如下:
//开启定时器
Coroutine coroutine = WaitTimeManager.WaitTime(5f,delegate {
Debug.Log("等待5秒后回调");
});
//等待过程中取消它
WaitTimeManager.CancelWait(ref coroutine);
二、间隔定时器
使用 CustomYieldInstruction 可以实现自定义协程。例如,设定总共持续 10 秒,但每隔 1 秒进行一次回调。
继承CustomYieldInstruction后,就可以处理自定义协程程序了。其中,keepWaiting表示是否继续让协程等待。通过判断时间,即可算出是否抛出间隔事件来实现这种间隔定时器。
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
public class CustomWait : CustomYieldInstruction
{
public override bool keepWaiting
{
get
{
//此方法返回false表示协程结束
if(Time.time - m_StartTime >= m_Time){
return false;
}else if(Time.time - m_LastTime >= m_Interval){
//更新上一次间隔时间
m_LastTime = Time.time;
m_IntervalCallback();
}
return true;
}
}
private UnityAction m_IntervalCallback;
private float m_StartTime;
private float m_LastTime;
private float m_Interval;
private float m_Time;
public CustomWait(float time, float interval, UnityAction callback)
{
//记录开始时间
m_StartTime = Time.time;
//记录上一次间隔时间
m_LastTime = Time.time;
//记录间隔调用时间
m_Interval = interval;
//记录总时间
m_Time = time;
//间隔回调
m_IntervalCallback = callback;
}
}
调用方法如下:
IEnumerator Start()
{
//10秒后结束
yield return new CustomWait(10f,1f,delegate() {
Debug.LogFormat("每过一秒回调一次 :{0}",Time.time);
});
Debug.Log("十秒结束");
}
总结
这篇文章介绍了在游戏开发中使用协程任务作为定时器的问题,以及两种解决方案。第一种方案是使用协程程序实现定时器功能,第二种是利用 CustomYieldInstruction 实现间隔定时器。这些方法的目的是为了在游戏开发中实现定时功能,例如在一定时间后触发特定事件或进行特定操作。希望大家可以更灵活地运用在工作和项目中,更快且有效的完成任务。