UI相关优化补充
This commit is contained in:
102
Assets/_Game/Scripts/UI/FloatingDamageTickSystem.cs
Normal file
102
Assets/_Game/Scripts/UI/FloatingDamageTickSystem.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BaseGames.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局伤害飘字 Tick 系统(架构 10_UIModule §10 优化)。
|
||||
///
|
||||
/// 设计动机:原实现中每条飘字独立 StartCoroutine(FloatAndFade),
|
||||
/// Boss 战或大范围 AOE 时同时存在数十条会产生大量协程对象与调度开销。
|
||||
/// 本系统用单一 Update + 紧凑 List<Entry> 集中推进,
|
||||
/// 所有飘字共享同一份每帧调度(仅一次 Update 调用),并消除协程对象。
|
||||
///
|
||||
/// 使用:FloatingDamageText.Show 不再 StartCoroutine,而是调用
|
||||
/// FloatingDamageTickSystem.Register(this, ...);系统自动在动画结束时
|
||||
/// 调用 OnComplete 回调(飘字 SetActive(false) 回池)。
|
||||
/// </summary>
|
||||
[DefaultExecutionOrder(+100)]
|
||||
public class FloatingDamageTickSystem : MonoBehaviour
|
||||
{
|
||||
private struct Entry
|
||||
{
|
||||
public FloatingDamageText Target;
|
||||
public Vector2 StartWorld;
|
||||
public float Elapsed;
|
||||
public float Duration;
|
||||
public float FloatDistance;
|
||||
public float StartAlpha;
|
||||
}
|
||||
|
||||
private static FloatingDamageTickSystem s_instance;
|
||||
private readonly List<Entry> _entries = new(64);
|
||||
|
||||
public static FloatingDamageTickSystem Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (s_instance != null) return s_instance;
|
||||
var go = new GameObject(nameof(FloatingDamageTickSystem));
|
||||
DontDestroyOnLoad(go);
|
||||
s_instance = go.AddComponent<FloatingDamageTickSystem>();
|
||||
return s_instance;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (s_instance != null && s_instance != this) { Destroy(this); return; }
|
||||
s_instance = this;
|
||||
}
|
||||
|
||||
public void Register(FloatingDamageText target, Vector2 startWorld,
|
||||
float duration, float floatDistance, float startAlpha)
|
||||
{
|
||||
if (target == null || duration <= 0f) return;
|
||||
_entries.Add(new Entry
|
||||
{
|
||||
Target = target,
|
||||
StartWorld = startWorld,
|
||||
Elapsed = 0f,
|
||||
Duration = duration,
|
||||
FloatDistance = floatDistance,
|
||||
StartAlpha = startAlpha
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>取消指定目标的飘字动画(例如对象池回收)。</summary>
|
||||
public void Unregister(FloatingDamageText target)
|
||||
{
|
||||
for (int i = _entries.Count - 1; i >= 0; i--)
|
||||
if (_entries[i].Target == target) _entries.RemoveAt(i);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
float dt = Time.deltaTime;
|
||||
// 倒序遍历,便于安全 RemoveAt
|
||||
for (int i = _entries.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var e = _entries[i];
|
||||
if (e.Target == null) { _entries.RemoveAt(i); continue; }
|
||||
|
||||
e.Elapsed += dt;
|
||||
float t = e.Elapsed / e.Duration;
|
||||
bool done = t >= 1f;
|
||||
if (done) t = 1f;
|
||||
|
||||
e.Target.TickAnimation(e.StartWorld, t, e.StartAlpha, e.FloatDistance);
|
||||
|
||||
if (done)
|
||||
{
|
||||
e.Target.OnTickComplete();
|
||||
_entries.RemoveAt(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
_entries[i] = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user