特效新内容。修复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
@@ -1,4 +1,4 @@
using UnityEngine;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections.Generic;
@@ -71,6 +71,25 @@ public class teamUIController : MonoBehaviour
public GameObject ally04_object;
public GameObject ally05_object;
[Header("Victory Animation")]
[Tooltip("The object to move when all enemies are defeated")]
public GameObject victoryMoveObject;
[Tooltip("Target X position (AnchoredPosition X for UI, World X for others)")]
public float victoryTargetX;
[Tooltip("Movement curve (Time 0->1, Value 0->1 recommended)")]
public AnimationCurve victoryMoveCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
[Tooltip("Duration of the movement in seconds")]
public float victoryMoveDuration = 2f;
[Tooltip("Delay before the victory animation starts (seconds)")]
public float victoryAnimationDelay = 3f;
[Tooltip("The image to fade saturation on victory")]
public Image victorySaturationImage;
[Tooltip("Duration for the saturation fade (seconds)")]
public float victorySaturationDuration = 2f;
private Coroutine _victoryMoveCoroutine;
private Coroutine _victorySaturationCoroutine;
[Header("Ally Statistics (Real-time)")]
[Tooltip("Total damage dealt to enemies by each of the 5 ally slots.")]
public float[] totalDamageDealt = new float[5];
@@ -997,6 +1016,18 @@ public class teamUIController : MonoBehaviour
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
// Saturation material assignment moved to PlayVictoryAnimation as requested
/*
// Initialize saturation image if assigned
if (victorySaturationImage != null && grayScaleMaterial != null)
{
// Assign the grayscale material instance to the image
victorySaturationImage.material = new Material(grayScaleMaterial);
// Use _Saturation property ID
victorySaturationImage.material.SetFloat(SaturationID, 1f);
}
*/
// Load ally slot IDs from PlayerPrefs
allySlotIds[0] = PlayerPrefs.GetInt("selected_heroSlot01_heroID", 0);
allySlotIds[1] = PlayerPrefs.GetInt("selected_heroSlot02_heroID", 0);
@@ -1371,7 +1402,7 @@ public class teamUIController : MonoBehaviour
// All enemies processed: show empty/finished state but keep UI visible
if (objectFather_enemy != null) objectFather_enemy.SetActive(true);
if (currentEnemy_nameText != null) currentEnemy_nameText.text = "(All Defeated)";
if (currentEnemy_characterImage != null) currentEnemy_characterImage.sprite = null;
// if (currentEnemy_characterImage != null) currentEnemy_characterImage.sprite = null;
if (currentEnemy_healthImage != null) currentEnemy_healthImage.fillAmount = 0f;
if (currentEnemy_fadehealthImage != null) currentEnemy_fadehealthImage.fillAmount = 0f;
if (currentEnemy_healthRate != null) currentEnemy_healthRate.text = "0/0";
@@ -1379,8 +1410,11 @@ public class teamUIController : MonoBehaviour
if (currentEnemy_fademanaImage != null) currentEnemy_fademanaImage.fillAmount = 0f;
if (currentEnemy_typeText != null) currentEnemy_typeText.text = "(普通敌人)";
UpdateEnemyListText();
// Documentation text normalized.
// Update total health bar to 0
UpdateAllEnemyTotalHealthUIImmediate();
// Trigger victory animation
PlayVictoryAnimation();
return;
}
@@ -1451,14 +1485,14 @@ public class teamUIController : MonoBehaviour
{
if (enemyList_rateText == null) return;
// 使用实际识别出的敌人数组长度作为总数
// Use actual recognized enemy count
int total = recognizedEnemySOs != null ? recognizedEnemySOs.Length : 0;
int displayIndex = 0;
if (total > 0)
{
// enemyCurrentCount 是从 0 开始的索引
// 确保显示编号在 1 total 之间
// enemyCurrentCount is 0-based index
// ensure display is 1 to total
displayIndex = Mathf.Clamp(enemyCurrentCount + 1, 1, total);
}
@@ -1467,6 +1501,96 @@ public class teamUIController : MonoBehaviour
enemyList_rateText.text = _sb.ToString();
}
private void PlayVictoryAnimation()
{
// 1. Victory Movement (Delayed)
if (victoryMoveObject != null)
{
if (_victoryMoveCoroutine != null) StopCoroutine(_victoryMoveCoroutine);
_victoryMoveCoroutine = StartCoroutine(VictoryMoveRoutine());
}
// 2. Victory Saturation Set (Immediate)
if (victorySaturationImage != null)
{
if (_victorySaturationCoroutine != null) StopCoroutine(_victorySaturationCoroutine);
// Assign material only when victory occurs
if (grayScaleMaterial != null)
{
victorySaturationImage.material = new Material(grayScaleMaterial);
}
// Immediately set saturation to 0 (Grayscale)
victorySaturationImage.material.SetFloat(SaturationID, 0f);
}
}
private IEnumerator VictoryMoveRoutine()
{
if (victoryMoveObject == null) yield break;
// Wait for the specified delay before starting movement
if (victoryAnimationDelay > 0f)
yield return new WaitForSeconds(victoryAnimationDelay);
float timer = 0f;
float duration = victoryMoveDuration > 0 ? victoryMoveDuration : 2f;
RectTransform rt = victoryMoveObject.GetComponent<RectTransform>();
Transform tf = victoryMoveObject.transform;
float startX = 0f;
bool isUI = (rt != null);
if (isUI) startX = rt.anchoredPosition.x;
else startX = tf.position.x;
// If curve is not set, default to EaseInOut
if (victoryMoveCurve == null || victoryMoveCurve.length == 0)
victoryMoveCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
while (timer < duration)
{
timer += Time.deltaTime;
float progress = Mathf.Clamp01(timer / duration);
float curveValue = victoryMoveCurve.Evaluate(progress);
float newX = Mathf.LerpUnclamped(startX, victoryTargetX, curveValue);
if (isUI)
{
Vector2 pos = rt.anchoredPosition;
pos.x = newX;
rt.anchoredPosition = pos;
}
else
{
Vector3 pos = tf.position;
pos.x = newX;
tf.position = pos;
}
yield return null;
}
// Final set
if (isUI)
{
Vector2 pos = rt.anchoredPosition;
pos.x = victoryTargetX;
rt.anchoredPosition = pos;
}
else
{
Vector3 pos = tf.position;
pos.x = victoryTargetX;
tf.position = pos;
}
}
// VictorySaturationRoutine removed as requested (immediate set)
private void OnEnemyDiedHandler(EnemyCombatant e)
{
// advance to next enemy after death