using System; using System.Threading; using Cysharp.Threading.Tasks; using TMPro; using UnityEngine; /// /// 自动隐藏脚本 /// 挂载在物体上,提供打开方法,打开后等待指定时间自动隐藏 /// 如果在等待期间再次调用打开方法,会重新计算等待时间 /// public class AutoHideScript : MonoBehaviour { [Header("自动隐藏设置")] [Tooltip("自动隐藏的延迟时间(秒)")] [SerializeField] private float hideDelay = 3f; [Tooltip("是否在开始时自动显示物体")] [SerializeField] private bool showOnStart = true; [Tooltip("是否启用调试日志")] [SerializeField] private bool enableDebugLog = true; [Header("CanvasGroup设置")] [Tooltip("显示时的透明度")] [SerializeField] private float showAlpha = 1f; [Tooltip("隐藏时的透明度")] [SerializeField] private float hideAlpha = 0f; [Tooltip("是否禁用交互(隐藏时)")] [SerializeField] private bool disableInteractionWhenHidden = true; // CanvasGroup组件引用 private CanvasGroup canvasGroup; // 用于取消当前等待任务的取消令牌源 private CancellationTokenSource cancellationTokenSource; // 当前是否正在等待隐藏 private bool isWaitingToHide = false; /// /// 脚本启动时的初始化 /// private void Start() { // 获取或添加CanvasGroup组件 canvasGroup = GetComponent(); if (canvasGroup == null) { canvasGroup = gameObject.AddComponent(); if (enableDebugLog) { Debug.Log($"AutoHideScript: 为物体 {gameObject.name} 添加了CanvasGroup组件"); } } SetCanvasGroupAlpha(hideAlpha); } /// /// 设置CanvasGroup的透明度 /// /// 透明度值(0-1) private void SetCanvasGroupAlpha(float alpha) { if (canvasGroup != null) { canvasGroup.alpha = alpha; // 根据透明度设置交互状态 if (disableInteractionWhenHidden) { canvasGroup.interactable = alpha > 0.1f; canvasGroup.blocksRaycasts = alpha > 0.1f; } } } /// /// 显示物体并开始计时隐藏 /// public void ShowObject(string title) { if (enableDebugLog) { Debug.Log($"AutoHideScript: 显示物体 {gameObject.name}"); } transform.Find("text").GetComponent().text = title; // 显示物体(使用CanvasGroup透明度) SetCanvasGroupAlpha(showAlpha); // 如果已经在等待隐藏,取消之前的等待任务 if (isWaitingToHide) { if (enableDebugLog) { Debug.Log($"AutoHideScript: 取消之前的隐藏任务,重新开始计时"); } CancelCurrentHideTask(); } // 开始新的隐藏等待任务 StartHideTask(); } /// /// 立即隐藏物体 /// public void HideObject() { if (enableDebugLog) { Debug.Log($"AutoHideScript: 立即隐藏物体 {gameObject.name}"); } // 取消当前的隐藏任务 CancelCurrentHideTask(); // 隐藏物体(使用CanvasGroup透明度) SetCanvasGroupAlpha(hideAlpha); } /// /// 取消当前的隐藏任务 /// private void CancelCurrentHideTask() { if (cancellationTokenSource != null) { cancellationTokenSource.Cancel(); cancellationTokenSource.Dispose(); cancellationTokenSource = null; } isWaitingToHide = false; } /// /// 开始隐藏等待任务 /// private void StartHideTask() { // 创建新的取消令牌源 cancellationTokenSource = new CancellationTokenSource(); isWaitingToHide = true; // 使用UniTask异步等待 WaitAndHideAsync(cancellationTokenSource.Token).Forget(); } /// /// 异步等待并隐藏物体 /// /// 取消令牌 private async UniTaskVoid WaitAndHideAsync(CancellationToken cancellationToken) { try { if (enableDebugLog) { Debug.Log($"AutoHideScript: 开始等待 {hideDelay} 秒后隐藏物体 {gameObject.name}"); } // 等待指定时间 await UniTask.Delay(TimeSpan.FromSeconds(hideDelay), cancellationToken: cancellationToken); // 等待完成后隐藏物体 if (gameObject != null) { if (enableDebugLog) { Debug.Log($"AutoHideScript: 等待完成,隐藏物体 {gameObject.name}"); } SetCanvasGroupAlpha(hideAlpha); } } catch (OperationCanceledException) { // 任务被取消,这是正常情况 if (enableDebugLog) { Debug.Log($"AutoHideScript: 隐藏任务被取消 {gameObject.name}"); } } catch (Exception ex) { // 处理其他异常 Debug.LogError($"AutoHideScript: 隐藏任务发生异常 {gameObject.name}: {ex.Message}"); } finally { // 清理状态 isWaitingToHide = false; } } /// /// 设置隐藏延迟时间 /// /// 延迟时间(秒) public void SetHideDelay(float delay) { hideDelay = Mathf.Max(0f, delay); if (enableDebugLog) { Debug.Log($"AutoHideScript: 设置隐藏延迟时间为 {hideDelay} 秒"); } } /// /// 获取当前是否正在等待隐藏 /// /// 如果正在等待隐藏返回true,否则返回false public bool IsWaitingToHide() { return isWaitingToHide; } /// /// 获取当前的隐藏延迟时间 /// /// 隐藏延迟时间(秒) public float GetHideDelay() { return hideDelay; } /// /// 脚本销毁时清理资源 /// private void OnDestroy() { CancelCurrentHideTask(); } /// /// 在Inspector中显示当前状态 /// private void OnValidate() { // 确保延迟时间不为负数 hideDelay = Mathf.Max(0f, hideDelay); // 确保透明度值在有效范围内 showAlpha = Mathf.Clamp01(showAlpha); hideAlpha = Mathf.Clamp01(hideAlpha); } }