| | |
| | | |
| | | using UnityEngine; |
| | | using System; |
| | | using UnityEngine.UI; |
| | | |
| | | public class BattleTips : MonoBehaviour |
| | | /// <summary> |
| | | /// 战斗飘字UI组件 |
| | | /// 职责:管理UI元素和与控制器的交互 |
| | | /// </summary> |
| | | public class BattleTips : MonoBehaviour, IBattleFloatingUI |
| | | { |
| | | public Vector2 beginPos = Vector2.zero; |
| | | public Vector2 endPos = new Vector2(0, 100); |
| | | public float showTime = 0.4f; |
| | | public float timer = 0f; |
| | | |
| | | protected RectTransform rectTransform; |
| | | |
| | | void Awake() |
| | | { |
| | | rectTransform = gameObject.AddMissingComponent<RectTransform>(); |
| | | } |
| | | |
| | | #region Inspector字段 |
| | | |
| | | [Header("UI Components")] |
| | | public RectTransform rectTransform; |
| | | public Text tipText; |
| | | public Text artText; |
| | | public Image background; |
| | | |
| | | [Header("Floating Config")] |
| | | [Tooltip("飘字动画配置,请在Inspector中拖拽赋值")] |
| | | public FloatingConfig floatingConfig; |
| | | |
| | | #endregion |
| | | |
| | | #region 公共字段 |
| | | |
| | | public Action OnFinish; |
| | | |
| | | // Buff 颜色相关 |
| | | private bool useBuffColor = false; |
| | | private bool isDebuff = false; |
| | | |
| | | #endregion |
| | | |
| | | public void SetText(string text) |
| | | #region 私有字段 |
| | | |
| | | // 移除 [SerializeField],controller 不应该被序列化 |
| | | public BattleFloatingUIController controller; |
| | | |
| | | #endregion |
| | | |
| | | |
| | | #region 公共方法 |
| | | |
| | | /// <summary> |
| | | /// 设置速度和缩放比例 |
| | | /// </summary> |
| | | public void SetRatio(float speed, float scale) |
| | | { |
| | | tipText.text = text; |
| | | rectTransform.anchoredPosition = Vector2.zero; |
| | | timer = 0f; |
| | | gameObject.SetActive(true); |
| | | EnsureControllerInitialized(); |
| | | controller?.SetRatio(speed, scale); |
| | | } |
| | | |
| | | |
| | | // 不要使用update |
| | | public void Run() |
| | | /// <summary> |
| | | /// 设置运行时位置(用于不跟随角色的飘字) |
| | | /// </summary> |
| | | public void SetPosition(Vector2 beginPos, Vector2 endPos) |
| | | { |
| | | if (timer >= showTime) |
| | | EnsureControllerInitialized(); |
| | | controller?.SetRuntimePosition(beginPos, endPos); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 运行时更新配置 |
| | | /// </summary> |
| | | public void SetFloatingConfig(FloatingConfig config) |
| | | { |
| | | floatingConfig = config; |
| | | |
| | | if (controller != null) |
| | | { |
| | | controller.SetConfig(config); |
| | | } |
| | | else |
| | | { |
| | | InitController(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置是否使用 Buff 颜色 |
| | | /// </summary> |
| | | public void SetBuffColor(bool useBuff, bool isDebuffBuff) |
| | | { |
| | | useBuffColor = useBuff; |
| | | isDebuff = isDebuffBuff; |
| | | |
| | | // 如果使用 buff 颜色,立即设置运行时颜色覆盖 |
| | | if (useBuffColor && floatingConfig != null) |
| | | { |
| | | Color buffColor = isDebuff ? floatingConfig.debuffColor : floatingConfig.gainBuffColor; |
| | | Color beginColor = new Color(buffColor.r, buffColor.g, buffColor.b, floatingConfig.beginColor.a); |
| | | Color endColor = new Color(buffColor.r, buffColor.g, buffColor.b, floatingConfig.endColor.a); |
| | | |
| | | EnsureControllerInitialized(); |
| | | controller?.SetRuntimeColor(beginColor, endColor); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 设置文本内容和样式 |
| | | /// </summary> |
| | | public void SetText(string text, bool useArtText = false, bool isCrit = false) |
| | | { |
| | | EnsureControllerInitialized(); |
| | | |
| | | // 切换文本显示类型 |
| | | SwitchTextDisplay(useArtText, text); |
| | | |
| | | // 开始播放 |
| | | Play(isCrit); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 显示/隐藏背景 |
| | | /// </summary> |
| | | public void ShowBackground(bool show) |
| | | { |
| | | if (background != null) |
| | | background.enabled = show; |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region IBattleFloatingUI接口实现 |
| | | |
| | | public void Play(bool isCrit, Action onComplete = null) |
| | | { |
| | | EnsureControllerInitialized(); |
| | | |
| | | if (controller == null) return; |
| | | |
| | | // 合并回调 |
| | | Action combinedCallback = () => |
| | | { |
| | | OnFinish?.Invoke(); |
| | | OnFinish = null; |
| | | gameObject.SetActive(false); |
| | | onComplete?.Invoke(); |
| | | }; |
| | | |
| | | controller.Play(isCrit, combinedCallback); |
| | | } |
| | | |
| | | public void Run() |
| | | { |
| | | controller?.Run(); |
| | | } |
| | | |
| | | public void Stop() |
| | | { |
| | | controller?.Stop(); |
| | | } |
| | | |
| | | public void Resume() |
| | | { |
| | | controller?.Resume(); |
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 私有方法 |
| | | |
| | | /// <summary> |
| | | /// 初始化控制器 |
| | | /// </summary> |
| | | private void InitController() |
| | | { |
| | | if (floatingConfig == null) |
| | | { |
| | | Debug.LogError($"[BattleTips] FloatingConfig 未配置! GameObject: {gameObject.name}"); |
| | | return; |
| | | } |
| | | |
| | | rectTransform.anchoredPosition = Vector2.Lerp(beginPos, endPos, timer / showTime); |
| | | timer += Time.deltaTime; |
| | | controller = new BattleFloatingUIController( |
| | | rectTransform, |
| | | gameObject, |
| | | ApplyColor, |
| | | floatingConfig |
| | | ); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 确保控制器已初始化 |
| | | /// </summary> |
| | | private void EnsureControllerInitialized() |
| | | { |
| | | if (controller == null || !controller.IsValid()) |
| | | InitController(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 切换文本显示类型 |
| | | /// </summary> |
| | | private void SwitchTextDisplay(bool useArtText, string text) |
| | | { |
| | | if (useArtText) |
| | | { |
| | | artText.text = text; |
| | | tipText.gameObject.SetActive(false); |
| | | artText.gameObject.SetActive(true); |
| | | } |
| | | else |
| | | { |
| | | tipText.text = text; |
| | | artText.gameObject.SetActive(false); |
| | | tipText.gameObject.SetActive(true); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 应用文本颜色(保留配置的透明度) |
| | | /// </summary> |
| | | private void ApplyTextColor(Color textColor) |
| | | { |
| | | if (floatingConfig != null) |
| | | { |
| | | Color colorWithAlpha = new Color( |
| | | textColor.r, |
| | | textColor.g, |
| | | textColor.b, |
| | | floatingConfig.beginColor.a |
| | | ); |
| | | ApplyColor(colorWithAlpha); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 应用颜色到激活的文本组件 |
| | | /// </summary> |
| | | private void ApplyColor(Color color) |
| | | { |
| | | if (tipText.gameObject.activeSelf) |
| | | tipText.color = color; |
| | | |
| | | if (artText.gameObject.activeSelf) |
| | | artText.color = color; |
| | | } |
| | | |
| | | #endregion |
| | | } |