【Unity笔记】Unity超时检测器开发:支持自定义重试次数与事件触发
在Unity游戏或应用开发中,我们经常会遇到需要检测超时的场景,比如:
- 等待用户在限定时间内完成某个交互;
- 等待网络请求或资源加载是否在规定时间内返回;
- 控制AI角色等待某个事件发生,超时后执行备选逻辑。
在这些场景中,如果仅检测一次是否超时,可能不够灵活。因此,我们本篇博客将带你一步步开发一个可复用的 TimeoutDetector Unity组件,支持以下功能:
- 自定义超时时间;
- 超时后自动重新检测;
- 支持设置最大重试次数;
- 每次超时与最终失败都能触发 UnityEvent;
- 可用于编辑器按钮中一键添加到 GameObject。
一、设计思路
我们希望 TimeoutDetector 具备如下能力:
- 计时:从调用
StartDetection()
开始倒计时,若超出timeoutDuration
则触发超时逻辑; - 重试机制:超时后自动重新计时,直到达到
maxRetryCount
次; - 事件触发:每次超时与最终失败都通过 UnityEvent 通知外部;
- 灵活配置:可在 Inspector 中设置超时时间、最大重试次数;
- 可复用组件:挂载即可使用,便于不同场景复用。
二、核心代码实现
以下是完整的 TimeoutDetector.cs
脚本代码:
using UnityEngine;
using UnityEngine.Events;
public class TimeoutDetector : MonoBehaviour
{
[Tooltip("超时时间(秒)")]
public float timeoutDuration = 5f;
[Tooltip("最大重试次数")]
public int maxRetryCount = 3;
[Tooltip("每次超时时触发的事件")]
public UnityEvent onTimeout;
[Tooltip("达到最大重试次数时触发的事件")]
public UnityEvent onMaxRetryReached;
private int currentRetryCount = 0;
private float timer = 0f;
private bool isTiming = false;
/// <summary>
/// 开始计时检测
/// </summary>
public void StartDetection()
{
currentRetryCount = 0;
RestartTimer();
}
/// <summary>
/// 手动停止检测
/// </summary>
public void StopDetection()
{
isTiming = false;
timer = 0f;
}
private void RestartTimer()
{
timer = 0f;
isTiming = true;
}
private void Update()
{
if (!isTiming) return;
timer += Time.deltaTime;
if (timer >= timeoutDuration)
{
HandleTimeout();
}
}
private void HandleTimeout()
{
isTiming = false;
onTimeout?.Invoke();
currentRetryCount++;
if (currentRetryCount < maxRetryCount)
{
Debug.Log($"Timeout occurred. Retrying {currentRetryCount}/{maxRetryCount}...");
RestartTimer(); // 再次启动超时检测
}
else
{
Debug.LogWarning("Max retry count reached.");
onMaxRetryReached?.Invoke(); // 触发最终失败事件
}
}
}
三、组件使用方式
1. 添加组件到物体
你可以手动添加 TimeoutDetector
到任意 GameObject,或使用我们提供的编辑器菜单:
using UnityEditor;
using UnityEngine;
public class TimeoutTool : EditorWindow
{
[MenuItem("Tools/Add TimeoutDetector Component")]
public static void AddTimeoutDetector()
{
GameObject selected = Selection.activeGameObject;
if (selected != null)
{
AddComponentIfMissing<TimeoutDetector>(selected);
}
else
{
Debug.LogError("请先选择一个 GameObject!");
}
}
private static void AddComponentIfMissing<T>(GameObject obj) where T : Component
{
if (obj.GetComponent<T>() == null)
{
obj.AddComponent<T>();
Debug.Log($"已添加组件:{typeof(T).Name}");
}
else
{
Debug.Log($"{typeof(T).Name} 已存在!");
}
}
}
菜单路径:Tools → Add TimeoutDetector Component
2. 场景中使用示例
public class TestTimeout : MonoBehaviour
{
public TimeoutDetector detector;
private void Start()
{
detector.onTimeout.AddListener(OnRetry);
detector.onMaxRetryReached.AddListener(OnFail);
detector.StartDetection(); // 启动检测
}
void OnRetry()
{
Debug.Log("超时一次,正在自动重试...");
}
void OnFail()
{
Debug.LogError("超时重试已达最大次数!");
}
}
你可以通过 Unity Inspector 绑定事件,或通过代码注册监听器。
四、应用场景举例
1. 网络请求等待超时
// 模拟:5秒内必须收到响应,否则重试3次
timeoutDetector.onTimeout.AddListener(() => RetryRequest());
timeoutDetector.onMaxRetryReached.AddListener(() => ShowNetworkError());
timeoutDetector.StartDetection();
2. 等待玩家交互
timeoutDetector.timeoutDuration = 10f;
timeoutDetector.maxRetryCount = 1;
timeoutDetector.onTimeout.AddListener(() => {
Debug.Log("玩家超时未响应,默认选择第一个选项");
ApplyDefaultChoice();
});
timeoutDetector.StartDetection();
五、优化建议与扩展方向
为了让该组件更加健壮和灵活,你还可以做如下扩展:
扩展方向 | 说明 |
---|---|
✅ 支持暂停恢复 | 在 Pause 状态下停止计时,恢复后继续 |
✅ 显示倒计时 | 将 timer 显示到 UI |
✅ 多状态触发 | 比如触发每秒回调,用于动态显示 |
✅ 支持协程实现 | 通过 IEnumerator 实现更清晰的控制流程 |
六、总结
本文从零实现了一个支持自动重试的 Unity 超时检测组件 TimeoutDetector
,它具备以下优点:
- 简洁易用,挂载即用;
- 高度复用,可应用于网络、交互、AI 等场景;
- 支持事件响应,方便扩展与组合逻辑;
- 可自定义超时时间与重试次数,适配不同业务需求。
通过本示例,你不仅能掌握 Unity 中的组件开发技巧,还能理解如何用面向对象的思维编写可复用的逻辑工具。希望对你在项目中实现更智能、更稳定的逻辑控制有所帮助。
👉 新开专栏《VR 360°全景视频开发》,持续更新中,敬请关注!
【专栏预告】《VR 360°全景视频开发:从GoPro到Unity VR眼镜应用实战》
《VR 360°全景视频开发》将带你深入探索从GoPro拍摄到Unity眼镜端应用开发的全流程技术。专栏内容涵盖安卓原生VR播放器开发、Unity VR视频渲染与手势交互、360°全景视频制作与优化,以及高分辨率视频性能优化等实战技巧。敬请关注每周更新的技术分享!