技能主要更新,修复卡顿并加入动画,以及各种其他更新。
This commit is contained in:
@@ -6,31 +6,42 @@ using UnityEngine;
|
||||
/// <summary>
|
||||
/// EffectSystem �ṩ����Ч����ͳһ�ַ��ӿڡ�
|
||||
/// - ѡ������Χ��Selector������Ŀ�꼯�ϣ��Լ���ȫ���Ѿ������Լ����Ѿ��������Ѿ������ϵ��ˡ������ˣ�
|
||||
/// - Ч�����ͣ�EffectType�������˼�ʱ/�������˺�/����/����/����ȡ�
|
||||
/// - Ч�����ͣ�EffectType�������˼�ʱ/�������˺�/����/����/����ȡ�?
|
||||
///
|
||||
/// Ŀ��ʵ��Ӧʵ�� ICombatant �ӿ��Ա� EffectSystem �ܵ���ͳһ�����������˺�/����/����ȣ����û��ʵ�֣�������־�����ѡ�
|
||||
///
|
||||
/// �ýű�Ϊ��ܣ����������弼�����ã�ֻ�ṩ ApplyEffect(...) �ȷ����������ű����á�
|
||||
/// �ýű�Ϊ��ܣ����������弼�����ã�ֻ��?ApplyEffect(...) �ȷ����������ű����á�
|
||||
/// </summary>
|
||||
public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
public static EffectSystem Instance { get; private set; }
|
||||
|
||||
// Per-frame caches to avoid repeated Find calls when multiple skills trigger in the same frame
|
||||
private int _cachedAlliesFrame = -1;
|
||||
private readonly List<GameObject> _cachedAllies = new List<GameObject>(8);
|
||||
private int _cachedEnemiesFrame = -1;
|
||||
private readonly List<GameObject> _cachedEnemies = new List<GameObject>(8);
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null) Instance = this;
|
||||
else Destroy(gameObject);
|
||||
}
|
||||
|
||||
private void LogVerbose(string message)
|
||||
{
|
||||
if (GameConfig.verboseLogs) Debug.Log(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ApplyEffect: ��ָ��ѡ������Χ��Ŀ��Ӧ��Ч����
|
||||
/// - selector: Ŀ��ѡ����
|
||||
/// - effectType: Ч�����ͣ���ʱ/�����ȣ�
|
||||
/// - amount: ��ֵ���˺�������������Ч��ǿ�ȣ�
|
||||
/// - duration: ����ʱ�䣨�Գ���Ч���� Buff/Debuff ��Ч������ʱЧ����Ϊ 0
|
||||
/// - source: �����ߣ����� Self/AlliesExceptSelf �жϻ��¼��
|
||||
/// - specificTarget: �� selector Ϊ CurrentEnemies ��ֻ��ָ������ʱ�ɴ������Ŀ��
|
||||
/// - tickInterval: ����Ч���� tick ������룩��Ĭ�� 1 ��
|
||||
/// - source: �����ߣ����� Self/AlliesExceptSelf �жϻ��¼��?
|
||||
/// - specificTarget: �� selector Ϊ CurrentEnemies ��ֻ��ָ������ʱ�ɴ������Ŀ��?
|
||||
/// - tickInterval: ����Ч���� tick ������룩��Ĭ��?1 ��
|
||||
/// </summary>
|
||||
public void ApplyEffect(Selector selector, EffectType effectType, float amount, float duration = 0f, GameObject source = null, GameObject specificTarget = null, float tickInterval = 1f)
|
||||
{
|
||||
@@ -288,7 +299,7 @@ public class EffectSystem : MonoBehaviour
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ally.attack += delta;
|
||||
ally.ModifyAttack(delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -316,7 +327,7 @@ public class EffectSystem : MonoBehaviour
|
||||
int delta = Mathf.CeilToInt(amount);
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ally.attack = Mathf.Max(0, ally.attack - delta);
|
||||
ally.ModifyAttack(-delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -335,6 +346,24 @@ public class EffectSystem : MonoBehaviour
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.RedirectNextDamageToSelf:
|
||||
{
|
||||
AllyCombatant redirector = null;
|
||||
if (source != null)
|
||||
redirector = source.GetComponent<AllyCombatant>() ?? source.GetComponentInChildren<AllyCombatant>(true);
|
||||
if (redirector == null && targets != null && targets.Count > 0)
|
||||
redirector = targets[0].GetComponent<AllyCombatant>() ?? targets[0].GetComponentInChildren<AllyCombatant>(true);
|
||||
if (redirector != null)
|
||||
{
|
||||
AllyCombatant.ActivateNextDamageRedirect(redirector, duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[EffectSystem] RedirectNextDamageToSelf: no AllyCombatant found to apply.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EffectType.IncreaseDamageResistance:
|
||||
foreach (var t in targets)
|
||||
{
|
||||
@@ -346,7 +375,7 @@ public class EffectSystem : MonoBehaviour
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ally.damageResistance = Mathf.Clamp01(ally.damageResistance + amount);
|
||||
Debug.Log($"[EffectSystem] IncreaseDamageResistance applied to {t.name}: new resistance={ally.damageResistance}");
|
||||
LogVerbose($"[EffectSystem] IncreaseDamageResistance applied to {t.name}: new resistance={ally.damageResistance}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -358,7 +387,7 @@ public class EffectSystem : MonoBehaviour
|
||||
if (duration <= 0f)
|
||||
{
|
||||
enemyR.damageResistance = Mathf.Clamp01(enemyR.damageResistance + amount);
|
||||
Debug.Log($"[EffectSystem] IncreaseDamageResistance applied to enemy {t.name}: new resistance={enemyR.damageResistance}");
|
||||
LogVerbose($"[EffectSystem] IncreaseDamageResistance applied to enemy {t.name}: new resistance={enemyR.damageResistance}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -378,7 +407,7 @@ public class EffectSystem : MonoBehaviour
|
||||
if (duration <= 0f)
|
||||
{
|
||||
ally.damageResistance = Mathf.Clamp01(ally.damageResistance - amount);
|
||||
Debug.Log($"[EffectSystem] DecreaseDamageResistance applied to {t.name}: new resistance={ally.damageResistance}");
|
||||
LogVerbose($"[EffectSystem] DecreaseDamageResistance applied to {t.name}: new resistance={ally.damageResistance}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -391,7 +420,7 @@ public class EffectSystem : MonoBehaviour
|
||||
if (duration <= 0f)
|
||||
{
|
||||
enemyR2.damageResistance = Mathf.Clamp01(enemyR2.damageResistance - amount);
|
||||
Debug.Log($"[EffectSystem] DecreaseDamageResistance applied to enemy {t.name}: new resistance={enemyR2.damageResistance}");
|
||||
LogVerbose($"[EffectSystem] DecreaseDamageResistance applied to enemy {t.name}: new resistance={enemyR2.damageResistance}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -418,7 +447,7 @@ public class EffectSystem : MonoBehaviour
|
||||
List<GameObject> list = new List<GameObject>();
|
||||
|
||||
// prefer teamUIController when available for authoritative ally/enemy objects
|
||||
var ui = teamUIController.Instance ?? FindObjectOfType<teamUIController>();
|
||||
var ui = teamUIController.Instance != null ? teamUIController.Instance : UnityEngine.Object.FindAnyObjectByType<teamUIController>();
|
||||
|
||||
switch (selector)
|
||||
{
|
||||
@@ -562,14 +591,17 @@ public class EffectSystem : MonoBehaviour
|
||||
if (uniq.Count == 0)
|
||||
Debug.LogWarning($"[EffectSystem] ResolveTargets -> selector={selector} returned 0 targets (source={(source ? source.name : "null")}, specificTarget={(specificTarget ? specificTarget.name : "null")})");
|
||||
else
|
||||
Debug.Log($"[EffectSystem] ResolveTargets -> selector={selector} resolved {uniq.Count} targets: {string.Join(",", uniq.ConvertAll(x => x != null ? x.name : "null"))}");
|
||||
LogVerbose($"[EffectSystem] ResolveTargets -> selector={selector} resolved {uniq.Count} targets: {string.Join(",", uniq.ConvertAll(x => x != null ? x.name : "null"))}");
|
||||
|
||||
return uniq;
|
||||
}
|
||||
|
||||
private IEnumerable<GameObject> FindAllAllies()
|
||||
{
|
||||
List<GameObject> allies = new List<GameObject>();
|
||||
if (_cachedAlliesFrame == Time.frameCount) return _cachedAllies;
|
||||
_cachedAlliesFrame = Time.frameCount;
|
||||
_cachedAllies.Clear();
|
||||
|
||||
// prefer teamUIController if available to get authoritative ally objects
|
||||
var ui = teamUIController.Instance;
|
||||
if (ui != null)
|
||||
@@ -580,7 +612,7 @@ public class EffectSystem : MonoBehaviour
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var go = ui.GetAllyObjectBySlot(i);
|
||||
if (go != null && !allies.Contains(go)) allies.Add(go);
|
||||
if (go != null && !_cachedAllies.Contains(go)) _cachedAllies.Add(go);
|
||||
}
|
||||
}
|
||||
catch { /* ignore and fallback */ }
|
||||
@@ -591,7 +623,7 @@ public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
string name = $"ally_0{i}"; // ally_01..ally_05
|
||||
var go = GameObject.Find(name);
|
||||
if (go != null && !allies.Contains(go)) allies.Add(go);
|
||||
if (go != null && !_cachedAllies.Contains(go)) _cachedAllies.Add(go);
|
||||
}
|
||||
|
||||
// also include objects tagged "Ally"
|
||||
@@ -599,52 +631,54 @@ public class EffectSystem : MonoBehaviour
|
||||
{
|
||||
var tagged = GameObject.FindGameObjectsWithTag("Ally");
|
||||
foreach (var g in tagged)
|
||||
if (!allies.Contains(g)) allies.Add(g);
|
||||
if (g != null && !_cachedAllies.Contains(g)) _cachedAllies.Add(g);
|
||||
}
|
||||
catch { /* tag might not exist; ignore */ }
|
||||
|
||||
return allies;
|
||||
return _cachedAllies;
|
||||
}
|
||||
|
||||
private IEnumerable<GameObject> FindAllEnemies()
|
||||
{
|
||||
List<GameObject> enemies = new List<GameObject>();
|
||||
if (_cachedEnemiesFrame == Time.frameCount) return _cachedEnemies;
|
||||
_cachedEnemiesFrame = Time.frameCount;
|
||||
_cachedEnemies.Clear();
|
||||
|
||||
// Prefer explicit EnemyCombatant components (more robust than tags)
|
||||
try
|
||||
{
|
||||
var comps = GameObject.FindObjectsOfType<EnemyCombatant>(true);
|
||||
var comps = UnityEngine.Object.FindObjectsByType<EnemyCombatant>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
||||
foreach (var c in comps)
|
||||
{
|
||||
if (c != null && c.gameObject != null && !enemies.Contains(c.gameObject)) enemies.Add(c.gameObject);
|
||||
if (c != null && c.gameObject != null && !_cachedEnemies.Contains(c.gameObject)) _cachedEnemies.Add(c.gameObject);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// Also include a single named instance if present
|
||||
var single = GameObject.Find("thisEnemy");
|
||||
if (single != null && !enemies.Contains(single)) enemies.Add(single);
|
||||
if (single != null && !_cachedEnemies.Contains(single)) _cachedEnemies.Add(single);
|
||||
|
||||
// Finally include any objects tagged "Enemy" (if tag exists)
|
||||
try
|
||||
{
|
||||
var tagged = GameObject.FindGameObjectsWithTag("Enemy");
|
||||
foreach (var g in tagged)
|
||||
if (!enemies.Contains(g)) enemies.Add(g);
|
||||
if (g != null && !_cachedEnemies.Contains(g)) _cachedEnemies.Add(g);
|
||||
}
|
||||
catch { /* ignore missing tag */ }
|
||||
|
||||
return enemies;
|
||||
return _cachedEnemies;
|
||||
}
|
||||
|
||||
#region Instant / OverTime Helpers
|
||||
private bool AreAllEnemiesDead()
|
||||
{
|
||||
var enemies = GameObject.FindObjectsOfType<EnemyCombatant>(true);
|
||||
if (enemies.Length == 0) return true;
|
||||
|
||||
foreach (var e in enemies)
|
||||
var enemies = FindAllEnemies();
|
||||
foreach (var go in enemies)
|
||||
{
|
||||
if (go == null) continue;
|
||||
var e = go.GetComponent<EnemyCombatant>();
|
||||
if (e != null && !e.IsDead && e.currentHP > 0)
|
||||
{
|
||||
return false;
|
||||
@@ -660,7 +694,7 @@ public class EffectSystem : MonoBehaviour
|
||||
// If target is an enemy, check if all enemies are already dead
|
||||
if (target.GetComponent<EnemyCombatant>() != null && AreAllEnemiesDead())
|
||||
{
|
||||
Debug.Log($"[EffectSystem] Skip ApplyInstantDamage to {target.name} because all enemies are dead.");
|
||||
LogVerbose($"[EffectSystem] Skip ApplyInstantDamage to {target.name} because all enemies are dead.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -731,7 +765,7 @@ public class EffectSystem : MonoBehaviour
|
||||
// check death state for immediate damage
|
||||
if (target.GetComponent<EnemyCombatant>() != null && AreAllEnemiesDead())
|
||||
{
|
||||
Debug.Log($"[EffectSystem] Skip DOT (immediate) to {target.name} because all enemies are dead.");
|
||||
LogVerbose($"[EffectSystem] Skip DOT (immediate) to {target.name} because all enemies are dead.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -758,7 +792,7 @@ public class EffectSystem : MonoBehaviour
|
||||
// check death state inside loop
|
||||
if (target.GetComponent<EnemyCombatant>() != null && AreAllEnemiesDead())
|
||||
{
|
||||
Debug.Log($"[EffectSystem] Stopping DOT to {target.name} because all enemies are dead.");
|
||||
LogVerbose($"[EffectSystem] Stopping DOT to {target.name} because all enemies are dead.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
@@ -937,9 +971,9 @@ public class EffectSystem : MonoBehaviour
|
||||
private IEnumerator ApplyTemporaryAttackChangeCoroutine(AllyCombatant ally, int delta, float duration)
|
||||
{
|
||||
if (ally == null) yield break;
|
||||
ally.attack = Mathf.Max(0, ally.attack + delta);
|
||||
ally.ModifyAttack(delta);
|
||||
yield return new WaitForSeconds(duration);
|
||||
ally.attack = Mathf.Max(0, ally.attack - delta);
|
||||
ally.ModifyAttack(-delta);
|
||||
}
|
||||
|
||||
// Coroutine to apply temporary attack change for EnemyCombatant
|
||||
@@ -952,3 +986,12 @@ public class EffectSystem : MonoBehaviour
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user