Files

221 lines
6.6 KiB
C#

using UnityEngine;
using UnityEngine.UI;
// using TMPro;
using System.Collections;
using Bansonic;
public class _gnp : MonoBehaviour
{
private const float DEFAULT_DISPLAY_DURATION = 0.5f;
private const float DEFAULT_FADE_TOTAL_TIME = 0.25f;
private const float DEFAULT_FADE_UP_DISTANCE = 20f;
private const float CANVAS_PLANE_DISTANCE = 10f;
private const string PREFAB_RESOURCE_NAME = "GlobalNoticeSystem";
private const string SCENE_INSTANCE_NAME = "GlobalNoticeSystem_SceneInstance";
[Header("UI Components")]
[SerializeField] private Text _noticeText;
[SerializeField] private Image _iconImage;
[SerializeField] private CanvasGroup _canvasGroup;
[Header("Icon Colors")]
[SerializeField] private Color _colorMessage = Color.white;
[SerializeField] private Color _colorRecommendation = Color.white;
[SerializeField] private Color _colorWarning = Color.yellow;
[SerializeField] private Color _colorError = Color.red;
[SerializeField] private Color _colorAlarm = Color.yellow;
[Header("Settings")]
[SerializeField] private float _displayDuration = DEFAULT_DISPLAY_DURATION;
[SerializeField] private float _fade_up_distance = DEFAULT_FADE_UP_DISTANCE;
[SerializeField] private float _fadeTotalTime = DEFAULT_FADE_TOTAL_TIME;
private Coroutine _fadeCoroutine;
private RectTransform _rectTransform;
private Vector3 _initialLocalPosition;
private static _gnp _currentInstance;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
private static void InitGlobalListener()
{
// 确保只订阅一次,避免重复
gNotice.OnNoticeDisplay -= StaticHandleDisplay;
gNotice.OnNoticeInterrupt -= StaticHandleInterrupt;
gNotice.OnNoticeDisplay += StaticHandleDisplay;
gNotice.OnNoticeInterrupt += StaticHandleInterrupt;
}
private static void StaticHandleDisplay(string prefix, string message, float? waitTime, float? fadeTotalTime)
{
// 如果已有实例,先销毁(单例模式,覆盖旧消息)
if (_currentInstance != null)
{
Destroy(_currentInstance.gameObject);
}
GameObject prefab = Resources.Load<GameObject>(PREFAB_RESOURCE_NAME);
if (prefab == null) return;
GameObject instance = Instantiate(prefab);
instance.name = SCENE_INSTANCE_NAME;
_currentInstance = instance.GetComponent<_gnp>();
if (_currentInstance != null)
{
_currentInstance.Display(prefix, message, waitTime, fadeTotalTime);
}
}
private static void StaticHandleInterrupt()
{
if (_currentInstance != null)
{
_currentInstance.Interrupt();
}
}
private void Awake()
{
_rectTransform = transform as RectTransform;
if (_rectTransform != null)
{
_initialLocalPosition = _rectTransform.localPosition;
}
if (_canvasGroup == null)
{
_canvasGroup = GetComponent<CanvasGroup>();
if (_canvasGroup == null)
{
_canvasGroup = gameObject.AddComponent<CanvasGroup>();
}
}
// 初始化 Canvas 设置
Canvas canvas = GetComponent<Canvas>();
if (canvas != null && canvas.renderMode == RenderMode.ScreenSpaceCamera)
{
Camera mainCam = Camera.main;
if (mainCam != null)
{
canvas.worldCamera = mainCam;
canvas.planeDistance = CANVAS_PLANE_DISTANCE;
}
else
{
Camera anyCam = SceneObjectLookupCache.FindFirst<Camera>();
if (anyCam != null)
{
canvas.worldCamera = anyCam;
}
}
}
SetComponentsActive(false);
SetCanvasAlpha(0f);
}
private void OnEnable()
{
// 实例被启用时的逻辑(如果需要)
}
private void OnDisable()
{
// 实例被禁用时的逻辑(如果需要)
}
private void OnDestroy()
{
if (_currentInstance == this)
{
_currentInstance = null;
}
}
public void Display(string prefix, string message, float? waitTime, float? fadeTotalTime)
{
Color iconColor = GetColorByPrefix(prefix);
float wait = waitTime ?? _displayDuration;
float fade = fadeTotalTime ?? _fadeTotalTime;
if (_noticeText != null) _noticeText.text = message ?? "null";
if (_iconImage != null) _iconImage.color = iconColor;
if (_rectTransform != null)
{
_rectTransform.localPosition = _initialLocalPosition;
}
SetCanvasAlpha(1f);
SetComponentsActive(true);
transform.SetAsLastSibling();
if (_fadeCoroutine != null) StopCoroutine(_fadeCoroutine);
_fadeCoroutine = StartCoroutine(FadeRoutine(wait, fade));
}
public void Interrupt()
{
// 立即销毁
if (gameObject != null)
{
Destroy(gameObject);
}
}
private IEnumerator FadeRoutine(float displayDuration, float fadeTotalTime)
{
if (displayDuration > 0f)
{
yield return new WaitForSeconds(displayDuration);
}
if (fadeTotalTime <= 0f)
{
SetCanvasAlpha(0f);
Destroy(gameObject);
yield break;
}
float elapsed = 0f;
while (elapsed < fadeTotalTime)
{
elapsed += Time.deltaTime;
float t = Mathf.Clamp01(elapsed / fadeTotalTime);
SetCanvasAlpha(1f - t);
if (_rectTransform != null)
{
_rectTransform.localPosition = _initialLocalPosition + Vector3.up * (_fade_up_distance * t);
}
yield return null;
}
SetCanvasAlpha(0f);
Destroy(gameObject);
}
private void SetComponentsActive(bool isActive)
{
if (_noticeText != null) _noticeText.gameObject.SetActive(isActive);
if (_iconImage != null) _iconImage.gameObject.SetActive(isActive);
}
private void SetCanvasAlpha(float value)
{
if (_canvasGroup != null) _canvasGroup.alpha = value;
}
private Color GetColorByPrefix(string prefix)
{
if (prefix.Contains("Info")) return _colorMessage;
if (prefix.Contains("Recommendation")) return _colorRecommendation;
if (prefix.Contains("Warning")) return _colorWarning;
if (prefix.Contains("Error")) return _colorError;
if (prefix.Contains("Alarm")) return _colorAlarm;
return _colorMessage;
}
}