Files
Gen_Hack-and-Slash-Roguelit…/Client/Assets/Scripts/Managers/MessageManager.cs

201 lines
9.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using Data;
using Prefab;
using UnityEngine;
using UnityEngine.SceneManagement; // 新增引用
using UnityEngine.UI; // 用于 LayoutGroup 和 RectTransform
using TMPro; // 用于 TMP_Text
namespace Managers
{
public class MessageManager:Utils.MonoSingleton<MessageManager>
{
private RectTransform _canvas;
private TemporaryAnimatorText _temporaryAnimatorTextPrefab; // 重命名,表示是预制体
private RectTransform _passiveHintContainer; // 用于PassiveHint的容器
// SceneManager.sceneLoaded 注册/取消注册
private void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
public void DisplayMessage(string message, PromptDisplayCategory type,Color? color=null)
{
if (!_canvas)
{
Debug.LogWarning($"MessageManager: Canvas is not available. Message '{message}' ignored.");
return;
}
switch (type)
{
case PromptDisplayCategory.FocusedEntityOverheadText:
if (Program.Instance.FocusedEntity == null)
return;
// GenerateTemporaryAnimation的第三个参数是显示时间
TemporaryAnimationManager.Instance.GenerateTemporaryAnimation(message,
Program.Instance.FocusedEntity.Position, 5); // 5秒显示时间
break;
case PromptDisplayCategory.Default:
case PromptDisplayCategory.PassiveHint:
if (_passiveHintContainer == null)
{
Debug.LogWarning("Cannot display PassiveHint: PassiveHintContainer is not available. Please ensure Canvas is present.");
return;
}
// 实例化消息文本作为PassiveHintContainer的子对象
var hintTextInstance = Instantiate(_temporaryAnimatorTextPrefab, _passiveHintContainer.transform);
// 确保它在Layout Group中正确显示
// var hintTextRect = hintTextInstance.GetComponent<RectTransform>();
// 如果temporaryAnimatorText有ContentSizeFitter这里可能不需要设置sizeDelta但为了LayoutGroup能识别可以添加LayoutElement
// var layoutElement = hintTextInstance.GetComponent<LayoutElement>();
// if (layoutElement == null) layoutElement = hintTextInstance.gameObject.AddComponent<LayoutElement>();
// layoutElement.minHeight = 30; // 最小高度
// layoutElement.preferredWidth = _passiveHintContainer.sizeDelta.x; // 适应容器的宽度
// 设置字体样式
var hintTmpText = hintTextInstance.text;
if (hintTmpText)
{
hintTmpText.fontSize = 24; // 较小的字体
hintTmpText.alignment = TextAlignmentOptions.TopLeft; // 左上对齐
hintTmpText.enableAutoSizing = false; // 关闭自动调整字体,保持统一
if(color.HasValue)
hintTmpText.color = color.Value;
}
hintTextInstance.Init(message); // Init 方法会处理动画和生命周期
// TemporaryAnimatorText 应该在 Init 内部设置好 lifeTime 并自动销毁。
break;
case PromptDisplayCategory.ScreenCenterLargeText:
var textInstance = GameObject.Instantiate(_temporaryAnimatorTextPrefab, _canvas.transform); // 使用预制体变量
// 设置RectTransform实现全屏
var textRect = textInstance.GetComponent<RectTransform>();
textRect.anchorMin = Vector2.zero; // (0,0)
textRect.anchorMax = Vector2.one; // (1,1)
textRect.offsetMin = Vector2.zero; // 左下角偏移为(0,0)
textRect.offsetMax = Vector2.zero; // 右上角偏移为(0,0)
// 获取TMP_Text并设置字体等
var tmpText = textInstance.GetComponent<TMP_Text>();
if (tmpText != null)
{
tmpText.fontSize = 80; // 设置一个较大的字体大小
tmpText.alignment = TextAlignmentOptions.Center; // 居中对齐
tmpText.enableAutoSizing = true; // 允许自动调整字体大小以适应文本框 (可选)
tmpText.SetText(message); // 先设置文本,确保布局计算正确
if(color.HasValue)
tmpText.color = color.Value;
}
textInstance.Init(message); // Init 方法会处理动画和生命周期
// textInstance.lifeTime 可以在 Init 方法内部设置,如果 Init 没有提供参数,这里就无法直接设置。
// 假设 Init 已经处理好生命周期。
break;
break;
case PromptDisplayCategory.FocusedEntityChatBubble:
break;
default:
throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
}
protected override void OnStart()
{
// 在单例第一次初始化时加载预制体
_temporaryAnimatorTextPrefab =
Resources.Load<TemporaryAnimatorText>("Prefab/TemporaryAnimation/UITemporaryAnimationText");
if (_temporaryAnimatorTextPrefab == null)
{
Debug.LogError("Failed to load TemporaryAnimatorText prefab. Check the path: Prefab/TemporaryAnimation/UITemporaryAnimationText");
}
// 首次启动时也尝试查找 Canvas 和创建 PassiveHint 容器
// 这可以处理管理器在 Canvas 和其他 UI 元素之前启动的情况
if (SceneManager.GetActiveScene().isLoaded)
{
OnSceneLoaded(SceneManager.GetActiveScene(), LoadSceneMode.Single);
}
}
/// <summary>
/// 场景加载完成回调用于查找并设置Canvas和PassiveHint容器
/// </summary>
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
// 尝试查找Canvas
var mainCanvas = FindAnyObjectByType<Canvas>(); // 查找场景中的第一个Canvas
if (mainCanvas != null)
{
_canvas = mainCanvas.GetComponent<RectTransform>();
InitializePassiveHintContainer();
}
else
{
_canvas = null;
// 如果没有Canvas确保容器也被清除避免引用无效对象
if (_passiveHintContainer != null)
{
Destroy(_passiveHintContainer.gameObject);
_passiveHintContainer = null;
}
Debug.LogWarning($"MessageManager: No Canvas found in scene '{scene.name}'. UI messages might not display.");
}
}
/// <summary>
/// 创建并初始化PassiveHint的UI容器
/// </summary>
private void InitializePassiveHintContainer()
{
if (_canvas == null)
{
Debug.LogError("Cannot initialize PassiveHint container: Canvas is null.");
return;
}
// 如果容器已经存在,先销毁旧的,确保每次场景加载都是新的容器
if (_passiveHintContainer != null)
{
Destroy(_passiveHintContainer.gameObject);
_passiveHintContainer = null;
}
// 创建一个新的GameObject作为容器
var containerGO = new GameObject("PassiveHintContainer");
_passiveHintContainer = containerGO.AddComponent<RectTransform>();
_passiveHintContainer.SetParent(_canvas, false); // false表示不保留世界坐标
// 设置容器的位置和大小:左侧中间
_passiveHintContainer.anchorMin = new Vector2(0, 0.5f);
_passiveHintContainer.anchorMax = new Vector2(0, 0.5f);
_passiveHintContainer.pivot = new Vector2(0, 0.5f); // 锚点和枢轴都在左中
_passiveHintContainer.anchoredPosition = new Vector2(0, 0); // 从左边距100示例值Y轴中心
_passiveHintContainer.sizeDelta = new Vector2(400, 600); // 示例宽度和高度
// 添加VerticalLayoutGroup
var layoutGroup = containerGO.AddComponent<VerticalLayoutGroup>();
layoutGroup.childAlignment = TextAnchor.UpperLeft; // 子元素靠左上排布
layoutGroup.spacing = 10; // 消息之间的间距
layoutGroup.padding = new RectOffset(10, 10, 10, 10); // 容器内边距
layoutGroup.childControlHeight = true;
layoutGroup.childForceExpandHeight = false;
}
}
}