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);
}
}