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(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(); if (_canvasGroup == null) { _canvasGroup = gameObject.AddComponent(); } } // 初始化 Canvas 设置 Canvas canvas = GetComponent(); 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 = FindFirstObjectByType(); 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; } }