技能主要更新,修复卡顿并加入动画,以及各种其他更新。

This commit is contained in:
FloatGaming
2026-02-07 21:05:17 +08:00
parent abeca51be5
commit 1ac3cd0104
1349 changed files with 1526749 additions and 24850 deletions
@@ -1,6 +1,6 @@
using UnityEngine;
using TMPro;
using System.Collections; // 保持对 Coroutine 的支持
using System.Collections; // ֶ Coroutine ֧
using System.Collections.Generic; // For List
public class AnimationController : MonoBehaviour
@@ -9,11 +9,11 @@ public class AnimationController : MonoBehaviour
public static AnimationController Global;
public GameObject redEffect; // 红色击打动画对象
public GameObject greenEffect; // 绿色击打动画对象
public GameObject yellowEffect; // 黄色击打动画对象
public GameObject purpleEffect; // 紫色击打动画对象
public GameObject blueEffect; // 蓝色击打动画对象
public GameObject redEffect; // ɫ򶯻
public GameObject greenEffect; // ɫ򶯻
public GameObject yellowEffect; // ɫ򶯻
public GameObject purpleEffect; // ɫ򶯻
public GameObject blueEffect; // ɫ򶯻
private Animator redAnimator;
private Animator greenAnimator;
@@ -25,35 +25,33 @@ public class AnimationController : MonoBehaviour
public GameObject hit_particular_object;
public GameObject hit_ring_object;
[Header("轨道颜色 (Hex Color Codes)")]
// F86F64 (浅红色/珊瑚色)
public string redColorHex = "#F86F64";
// 40EC90 (亮绿色)
public string greenColorHex = "#40EC90";
// F7CB6C (金黄色)
public string yellowColorHex = "#F7CB6C";
// F888E7 (亮粉色/洋红色)
public string purpleColorHex = "#F888E7";
// 4FACFE (天蓝色)
public string blueColorHex = "#4FACFE";
[Header("Hold 粒子配置")]
[Header("ɫ (Hex Color Codes)")]
public string redColorHex = "#FF9390";
public string greenColorHex = "#38F6CA";
public string yellowColorHex = "#FFE1A2";
public string purpleColorHex = "#F083E4";
public string blueColorHex = "#7AF9FF";
[Header("Hold ")]
public float holdParticleInterval = 0.2f;
private Coroutine holdParticleCoroutine;
private bool holdActive = false;
private string currentHoldColor;
private bool isHolding = false;
private WaitForSeconds cachedHoldWait;
private float cachedHoldWaitSeconds = -1f;
private static bool loggedMissingHitParticleSource;
// Track active particle instances for immediate cleanup
private List<GameObject> activeParticles = new List<GameObject>();
[Header("判定飘字prefabs")]
[Header("жƮprefabs")]
public GameObject perfect_judge_prefab;
public GameObject great_judge_prefab;
public GameObject good_judge_prefab;
public GameObject miss_judge_prefab;
[Header("轨道关联的判定文字 (Legacy Text)")]
// 请在 Inspector 中将对应的 UI Text 拖入
[Header("ж (Legacy Text)")]
// Inspector нӦ UI Text
public TextMeshProUGUI red_track_judgementText;
public TextMeshProUGUI green_track_judgementText;
public TextMeshProUGUI yellow_track_judgementText;
@@ -124,7 +122,13 @@ public class AnimationController : MonoBehaviour
{
while (holdActive)
{
yield return new WaitForSeconds(Mathf.Max(0.01f, holdParticleInterval));
float waitSeconds = Mathf.Max(0.01f, holdParticleInterval);
if (cachedHoldWait == null || !Mathf.Approximately(cachedHoldWaitSeconds, waitSeconds))
{
cachedHoldWaitSeconds = waitSeconds;
cachedHoldWait = new WaitForSeconds(waitSeconds);
}
yield return cachedHoldWait;
if (!holdActive) break;
PlayDestroyAnimation(color);
}
@@ -143,7 +147,7 @@ public class AnimationController : MonoBehaviour
Global = this;
DontDestroyOnLoad(gameObject);
Debug.Log("[AnimationController] Global AnimationController registered");
if (JudgeManager.IsDebugEnabled) Debug.Log("[AnimationController] Global AnimationController registered");
}
// Animator cache
@@ -164,7 +168,7 @@ public class AnimationController : MonoBehaviour
if (byTag != null)
{
hit_particular_object = byTag;
Debug.Log("AnimationController: assigned hit_particular_object via tag 'HitParticleSource'.");
if (JudgeManager.IsDebugEnabled) Debug.Log("AnimationController: assigned hit_particular_object via tag 'HitParticleSource'.");
}
}
catch { }
@@ -176,15 +180,16 @@ public class AnimationController : MonoBehaviour
if (byName != null)
{
hit_particular_object = byName;
Debug.Log("AnimationController: assigned hit_particular_object via GameObject.Find by name.");
if (JudgeManager.IsDebugEnabled) Debug.Log("AnimationController: assigned hit_particular_object via GameObject.Find by name.");
}
}
if (hit_particular_object == null)
{
Debug.LogWarning("AnimationController: hit_particular_object not assigned in Inspector and automatic lookup failed.\n" +
"You can either assign a scene object to 'hit_particular_object' on the prefab instance in the scene,\n" +
"or tag the scene particle source with 'HitParticleSource', or place a GameObject named 'HitParticleSource' in the scene.");
if (JudgeManager.IsDebugEnabled)
Debug.LogWarning("AnimationController: hit_particular_object not assigned in Inspector and automatic lookup failed.\n" +
"You can either assign a scene object to 'hit_particular_object' on the prefab instance in the scene,\n" +
"or tag the scene particle source with 'HitParticleSource', or place a GameObject named 'HitParticleSource' in the scene.");
}
}
}
@@ -194,7 +199,11 @@ public class AnimationController : MonoBehaviour
// Only use the scene object as the template. No prefab fallback.
if (hit_particular_object == null)
{
Debug.LogError("hit_particular_object is null. Assign a scene particle source to AnimationController.hit_particular_object or tag a GameObject 'HitParticleSource'.");
if (!loggedMissingHitParticleSource)
{
loggedMissingHitParticleSource = true;
Debug.LogError("hit_particular_object is null. Assign a scene particle source to AnimationController.hit_particular_object or tag a GameObject 'HitParticleSource'.");
}
// As a fallback, trigger the Animator-based effects
TriggerAnimatorEffect(color);
return;
@@ -214,15 +223,15 @@ public class AnimationController : MonoBehaviour
case "blue": if (blueEffect != null) { spawnPos = blueEffect.transform.position; parentTransform = blueEffect.transform; } break;
}
// 获取并解析颜色
// ȡɫ
Color trackColor;
string hexCode = GetHexCodeForColor(color);
// 尝试解析 16 进制颜色代码。如果失败,使用白色作为默认值。
// Խ 16 ɫʧܣʹðɫΪĬֵ
if (!ColorUtility.TryParseHtmlString(hexCode, out trackColor))
{
trackColor = Color.white;
Debug.LogWarning($"Failed to parse hex color for '{color}' ({hexCode}). Using white.");
if (JudgeManager.IsDebugEnabled) Debug.LogWarning($"Failed to parse hex color for '{color}' ({hexCode}). Using white.");
}
SpawnJudgePrefabByTrackText(color);
@@ -281,7 +290,7 @@ public class AnimationController : MonoBehaviour
GameObject ringInstance = Instantiate(hit_ring_object, spawnPos, Quaternion.identity);
if (ringInstance != null)
{
Debug.Log($"AnimationController: instantiated hit_ring_object '{ringInstance.name}' at {spawnPos}. parentTransform={(parentTransform != null ? parentTransform.name : "null")} ");
if (JudgeManager.IsDebugEnabled) Debug.Log($"AnimationController: instantiated hit_ring_object '{ringInstance.name}' at {spawnPos}. parentTransform={(parentTransform != null ? parentTransform.name : "null")} ");
// Parent before activation to avoid transform surprises when Simulation Space = Local
if (parentTransform != null)
@@ -289,14 +298,14 @@ public class AnimationController : MonoBehaviour
ringInstance.transform.SetParent(parentTransform, false);
// keep world position at spawnPos
ringInstance.transform.position = spawnPos;
Debug.Log("AnimationController: ringInstance parent set to " + parentTransform.name);
if (JudgeManager.IsDebugEnabled) Debug.Log("AnimationController: ringInstance parent set to " + parentTransform.name);
}
// Activate after parenting
ringInstance.SetActive(true);
var ringSystems = ringInstance.GetComponentsInChildren<ParticleSystem>(true);
Debug.Log("AnimationController: ringSystems count=" + (ringSystems != null ? ringSystems.Length : 0));
if (JudgeManager.IsDebugEnabled) Debug.Log("AnimationController: ringSystems count=" + (ringSystems != null ? ringSystems.Length : 0));
if (ringSystems != null && ringSystems.Length > 0)
{
float ringMaxLife = 0f;
@@ -304,7 +313,7 @@ public class AnimationController : MonoBehaviour
{
var rmain = rps.main;
// log important runtime properties for debugging
Debug.Log($"ring PS: {rps.gameObject.name} simulationSpace={rmain.simulationSpace} startLifetime={rmain.startLifetime.constant} startColor={rmain.startColor.color}");
if (JudgeManager.IsDebugEnabled) Debug.Log($"ring PS: {rps.gameObject.name} simulationSpace={rmain.simulationSpace} startLifetime={rmain.startLifetime.constant} startColor={rmain.startColor.color}");
// reuse same track color
rmain.startColor = trackColor;
@@ -319,7 +328,7 @@ public class AnimationController : MonoBehaviour
{
var emission = rps.emission;
var rate = emission.rateOverTime;
Debug.Log($"ring PS emission rateOverTime.constant (approx) = {rate.constant}");
if (JudgeManager.IsDebugEnabled) Debug.Log($"ring PS emission rateOverTime.constant (approx) = {rate.constant}");
}
catch { }
}
@@ -331,7 +340,7 @@ public class AnimationController : MonoBehaviour
}
else
{
Debug.LogWarning("hit_ring_object has no ParticleSystem components");
if (JudgeManager.IsDebugEnabled) Debug.LogWarning("hit_ring_object has no ParticleSystem components");
Destroy(ringInstance);
}
}
@@ -342,7 +351,7 @@ public class AnimationController : MonoBehaviour
}
}
// 用于根据颜色名称获取对应的 16 进制代码
// ڸɫƻȡӦ 16 ƴ
private string GetHexCodeForColor(string color)
{
switch (color)
@@ -352,7 +361,7 @@ public class AnimationController : MonoBehaviour
case "yellow": return yellowColorHex;
case "purple": return purpleColorHex;
case "blue": return blueColorHex;
default: return "#FFFFFF"; // 默认返回白色
default: return "#FFFFFF"; // ĬϷذɫ
}
}
@@ -399,14 +408,14 @@ public class AnimationController : MonoBehaviour
}
}
/// <summary>
/// 根据传入的颜色频道,定位到对应的 UI Text 并读取其内容
/// ݴɫƵλӦ UI Text ȡ
/// </summary>
private void SpawnJudgePrefabByTrackText(string color)
{
TextMeshProUGUI targetText = null;
Transform spawnPoint = null;
// 1. 匹配对应的文本组件和位置
// 1. ƥӦıλ
switch (color)
{
case "red": targetText = red_track_judgementText; spawnPoint = redEffect != null ? redEffect.transform : null; break;
@@ -417,11 +426,11 @@ public class AnimationController : MonoBehaviour
}
if (targetText != null && spawnPoint != null)
{
// 打印调试信息,看程序到底读到了什么文字
Debug.LogError($"轨道 {color} 当前读到的文字: [{targetText.text}]");
// 打印调试信息,确认判定到底读取到的是什么文字
if (JudgeManager.IsDebugEnabled) Debug.Log($"判定 {color} 当前读到的文字: [{targetText.text}]");
}
// 2. 如果找到了文本且文本不为空,则执行喷出逻辑
// 2. ҵııΪգִ߼
if (targetText != null && spawnPoint != null && !string.IsNullOrEmpty(targetText.text))
{
DoExecutePrefabSpawn(targetText.text, spawnPoint);
@@ -429,13 +438,13 @@ public class AnimationController : MonoBehaviour
}
/// <summary>
/// 最终执行实例化的函数
/// ִʵĺ
/// </summary>
private void DoExecutePrefabSpawn(string judgeResult, Transform spawnTransform)
{
GameObject prefabToUse = null;
// 字符串匹配(需确保与 InputManager 中传入的字符串一致)
// ַƥȷ InputManager дַһ£
if (judgeResult.Contains("Perfect")) prefabToUse = perfect_judge_prefab;
else if (judgeResult.Contains("Great")) prefabToUse = great_judge_prefab;
else if (judgeResult.Contains("Good")) prefabToUse = good_judge_prefab;
@@ -443,10 +452,10 @@ public class AnimationController : MonoBehaviour
if (prefabToUse != null)
{
// 在对应特效点生成判定 Prefab
// ڶӦЧж Prefab
GameObject instance = Instantiate(prefabToUse, spawnTransform.position, Quaternion.identity);
// 自动销毁,防止堆积
// Զ٣ֹѻ
Destroy(instance, 1.0f);
}
}
@@ -524,4 +533,4 @@ public class AnimationController : MonoBehaviour
{
yield return StartCoroutine(PrewarmCoroutine(perTemplate));
}
}
}