特效新内容。修复gameplay致命bug和分数保存bug

This commit is contained in:
2026-02-16 01:55:18 +08:00
parent 3a7a0b4669
commit 9f7c1c57b7
206 changed files with 112684 additions and 857 deletions
+111 -6
View File
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@@ -88,12 +88,19 @@ public class AllyCombatant : MonoBehaviour, ICombatant
private Vector3[] skillIconBaseScales;
private bool[] skillIconBaseScaleCached;
[Tooltip("最多显示的已释放技能图标数量 (默认1)")]
public int maxSkillHistoryCount = 1;
[Tooltip("无新技能释放时,技能图标自动渐隐的时间 (秒)")]
public float skillIconAutoFadeTime = 2f;
private Coroutine fadeHealthCoroutine;
private Coroutine fadeManaCoroutine;
private List<Buff> activeBuffs = new List<Buff>();
private Coroutine skillIconEnterCoroutine;
private Image skillIconEnterAnimatingImage;
private Coroutine skillIconAutoFadeCoroutine;
private float lastSkillIconPushTime = -1f;
// Track skills that are currently active because HP percent condition is satisfied.
private HashSet<string> _activeHpPercentSkills = new HashSet<string>();
@@ -146,6 +153,32 @@ public class AllyCombatant : MonoBehaviour, ICombatant
if (GameConfig.verboseLogs) Debug.Log(message);
}
private void Update()
{
// Check for skill icon auto-fade
if (Application.isPlaying && skillIconAutoFadeTime > 0f && lastSkillIconPushTime > 0f)
{
// Only start coroutine if not already running and time exceeded
if (skillIconAutoFadeCoroutine == null && Time.time - lastSkillIconPushTime >= skillIconAutoFadeTime)
{
// Double check visibility
bool anyVisible = false;
if (skillIconOccupied != null)
{
for (int i = 0; i < skillIconOccupied.Length; i++)
{
if (skillIconOccupied[i]) { anyVisible = true; break; }
}
}
if (anyVisible)
{
skillIconAutoFadeCoroutine = StartCoroutine(SkillIconAutoFadeRoutine());
}
}
}
}
private void Start()
{
// Resolve UI and optionally pull data from SO
@@ -482,6 +515,13 @@ public class AllyCombatant : MonoBehaviour, ICombatant
Image slot = skillIconSlots[i];
if (slot == null) continue;
// Enforce max count
if (i >= maxSkillHistoryCount)
{
slot.enabled = false;
continue;
}
bool occupied = i < skillIconOccupied.Length && skillIconOccupied[i];
slot.enabled = occupied || slot.sprite != null;
@@ -554,16 +594,29 @@ public class AllyCombatant : MonoBehaviour, ICombatant
if (icon == null) return;
if (skillIconSlots == null || skillIconSlots.Length == 0) ResolveHudExtras();
if (skillIconSlots == null || skillIconSlots.Length == 0) return;
// Reset auto-fade logic
lastSkillIconPushTime = Time.time;
if (skillIconAutoFadeCoroutine != null)
{
StopCoroutine(skillIconAutoFadeCoroutine);
skillIconAutoFadeCoroutine = null;
}
int limit = Mathf.Clamp(maxSkillHistoryCount, 0, skillIconSlots.Length);
if (limit <= 0) return;
EnsureSkillIconSlotScaleCache();
NormalizeSkillIconSlotsVisualState();
// Capture the icon being pushed out (oldest) for exit animation.
Image lastSlot = skillIconSlots[skillIconSlots.Length - 1];
// Capture the icon being pushed out (oldest active within limit) for exit animation.
int lastIndex = limit - 1;
Image lastSlot = skillIconSlots[lastIndex];
Sprite removedSprite = null;
Color removedColor = Color.white;
bool removedOccupied = skillIconOccupied != null &&
skillIconSlots.Length - 1 < skillIconOccupied.Length &&
skillIconOccupied[skillIconSlots.Length - 1];
lastIndex < skillIconOccupied.Length &&
skillIconOccupied[lastIndex];
if (removedOccupied && lastSlot != null && lastSlot.sprite != null)
{
removedSprite = lastSlot.sprite;
@@ -571,7 +624,7 @@ public class AllyCombatant : MonoBehaviour, ICombatant
}
// Shift down (oldest drops off the end).
for (int i = skillIconSlots.Length - 1; i > 0; i--)
for (int i = lastIndex; i > 0; i--)
{
var prev = skillIconSlots[i - 1];
var cur = skillIconSlots[i];
@@ -601,6 +654,19 @@ public class AllyCombatant : MonoBehaviour, ICombatant
skillIconOccupied[0] = true;
PlaySkillIconEnterAnim(first);
}
// Clear slots beyond limit
for (int i = limit; i < skillIconSlots.Length; i++)
{
if (skillIconSlots[i] != null)
{
skillIconSlots[i].sprite = null;
skillIconSlots[i].enabled = false;
}
if (skillIconOccupied != null && i < skillIconOccupied.Length)
skillIconOccupied[i] = false;
}
ApplySkillIconSlotVisibility();
// Play exit animation for the removed icon (if any).
@@ -610,6 +676,45 @@ public class AllyCombatant : MonoBehaviour, ICombatant
}
}
private IEnumerator SkillIconAutoFadeRoutine()
{
if (skillIconSlots == null || skillIconOccupied == null)
{
skillIconAutoFadeCoroutine = null;
yield break;
}
// Fading from Left to Right (0 -> N)
// Assuming slot 0 is the newest and leftmost.
// If the user meant visual order, 0 is usually left.
int limit = Mathf.Clamp(maxSkillHistoryCount, 0, skillIconSlots.Length);
for (int i = 0; i < limit; i++)
{
if (i >= skillIconOccupied.Length) break;
// If new skill interrupts, this coroutine is stopped by PushSkillIcon
if (skillIconOccupied[i] && skillIconSlots[i] != null && skillIconSlots[i].sprite != null)
{
// Play exit animation for this slot
PlaySkillIconExitAnim(skillIconSlots[i], skillIconSlots[i].sprite, skillIconSlots[i].color);
// Clear the slot
skillIconSlots[i].sprite = null;
skillIconSlots[i].enabled = false;
skillIconOccupied[i] = false;
// Wait small interval between fades
yield return new WaitForSeconds(0.15f);
}
}
ApplySkillIconSlotVisibility();
skillIconAutoFadeCoroutine = null;
// Reset time so it doesn't loop immediately (though checks anyVisible)
lastSkillIconPushTime = -1f;
}
private void PlaySkillIconEnterAnim(Image img)
{
if (img == null) return;