超大量的更新 修复很多问题,gameplay特效初步

This commit is contained in:
2026-02-14 23:46:20 +08:00
parent ef8eb67259
commit 3a7a0b4669
360 changed files with 85670 additions and 4144 deletions
@@ -36,15 +36,15 @@ public class BeatmapManager : MonoBehaviour
Debug.LogWarning($"BeatmapManager.AcceptSongData: accepted song={(song==null?"NULL":song.songName)}, difficulty={difficulty}");
}
public Beatmap beatmap; // ǰ
public Beatmap beatmap; // Documentation text normalized.
//
// Documentation text normalized.
public NoteSpawner noteSpawner;
// teamUIController ãֱקֵ
// Documentation text normalized.
public teamUIController uiController;
public Image bgSpriteImage; // ͼƬ
public Image bgSpriteImage; // Documentation text normalized.
public GameObject bgSpriteObject;
public Image startCanvas_image;
@@ -82,7 +82,7 @@ public class BeatmapManager : MonoBehaviour
public float imMultiplier = 3f;
[Header("HP Calculation Settings")]
[Tooltip("Scales the note amount to enemy HP. Example: NoteAmount * MaxMultiplier * BaseScale TotalHP")]
[Tooltip("Documentation text normalized.")]
public float baseHpUnitScale = 1f;
// Total chart score and per-note score fields
@@ -90,23 +90,23 @@ public class BeatmapManager : MonoBehaviour
public int perNoteScore;
public int leftoverScore;
// JSON ļ
// Documentation text normalized.
public void LoadBeatmap(string fileName)
{
string path = Application.streamingAssetsPath + "/" + fileName;
if (File.Exists(path))
{
string json = File.ReadAllText(path);
Debug.Log(" JSON Ѷȡ: " + path);
Debug.Log("读取 JSON 路径: " + path);
ProcessJsonAndLoad(json);
}
else
{
Debug.LogError("ļڣ" + path);
Debug.LogError("文件未找到: " + path);
}
}
// ԭʼ JSON ַ·ȶȡ
// Documentation text normalized.
public void LoadBeatmapFromJsonString(string json)
{
if (string.IsNullOrEmpty(json))
@@ -117,7 +117,7 @@ public class BeatmapManager : MonoBehaviour
ProcessJsonAndLoad(json);
}
// JSON NoteSpawner test mode ӳٿʼ
// Documentation text normalized.
public bool ParseJsonOnly(string json)
{
if (string.IsNullOrEmpty(json))
@@ -134,13 +134,13 @@ public class BeatmapManager : MonoBehaviour
}
catch (System.Exception ex)
{
Debug.LogError($"ParseJsonOnly Beatmap ʧ: {ex}");
Debug.LogError($"ParseJsonOnly 解析 Beatmap 失败: {ex}");
return false;
}
if (parsed == null)
{
Debug.LogError("ParseJsonOnly: Beatmap null");
Debug.LogError("ParseJsonOnly: 解析 Beatmap 结果为 null");
return false;
}
@@ -201,14 +201,14 @@ public class BeatmapManager : MonoBehaviour
}
// Calculate per-note and leftover scores
CalculateNoteScores();
CalculateNoteScores(parsed);
// NOTE: Do NOT modify parsed.notes here. globalDelaySeconds will be applied to audio playback instead.
beatmap = parsed;
Debug.Log("ParseJsonOnly: parsed beatmap " + beatmap.title);
// ͳһĵ˴߼ HP ã
// Documentation text normalized.
SetupEnemiesAndHP();
ApplyTrackScoreCaps(beatmap);
ApplyTrackScoreCaps(beatmap);
@@ -216,17 +216,19 @@ public class BeatmapManager : MonoBehaviour
return true;
}
// ֱӴѾ Beatmapݾɵã
// Documentation text normalized.
public void LoadBeatmap(Beatmap loadedBeatmap)
{
beatmap = loadedBeatmap;
Debug.Log("Ѽأ Beatmap 󣩣" + (beatmap != null ? beatmap.title : "null"));
parsedNoteAmount = (beatmap != null && beatmap.notes != null) ? beatmap.notes.Length : 0;
CalculateNoteScores(beatmap);
Debug.Log("谱面加载完成,当前 Beatmap 标题: " + (beatmap != null ? beatmap.title : "null"));
// No globalDelaySeconds available in this path. Call NoteSpawner directly.
noteSpawner.LoadBeatmap(beatmap);
ApplyTrackScoreCaps(beatmap);
}
// ȡصǰã
// Documentation text normalized.
public void LoadBeatmapFromFile()
{
string path = Application.streamingAssetsPath + "/Emilia_demo.json";
@@ -237,11 +239,11 @@ public class BeatmapManager : MonoBehaviour
}
else
{
Debug.LogError("ļδҵ");
Debug.LogError("默认谱面文件未找到");
}
}
// TextAsset parseOnly ǷֻǽֱӼ
// Documentation text normalized.
public bool LoadBeatmapFromTextAsset(TextAsset chartAsset, bool parseOnly = false)
{
if (chartAsset == null)
@@ -265,7 +267,7 @@ public class BeatmapManager : MonoBehaviour
}
}
// SongData chart TextAsset
// Documentation text normalized.
public bool LoadBeatmapFromSongData(SongData song, int difficulty, bool parseOnly = false)
{
if (song == null)
@@ -283,18 +285,27 @@ public class BeatmapManager : MonoBehaviour
return LoadBeatmapFromTextAsset(ta, parseOnly);
}
// Start() гʼ
// Documentation text normalized.
void Start()
{
// һݹ SongDataͨ BeatmapManager.pendingSongData
// 如果 assignedSongData 为空,尝试从 SongDataHolder 获取,作为最后的兜底
if (pendingSongData == null && assignedSongData == null)
{
assignedSongData = SongDataHolder.SelectedSongData;
Debug.Log($"[BeatmapManager] No pending song, fallback to SongDataHolder: {(assignedSongData != null ? assignedSongData.songName : "null")}");
}
// 无论如何,在加载谱面前先同步敌人编队到 teamUIController
SyncEnemyListToUI();
if (pendingSongData != null)
{
Debug.LogWarning($"BeatmapManager.Start: pendingSongData detected: {pendingSongData.songName}, difficulty={pendingDifficulty}");
// pending ʾ Inspector ֶΣڼ
// Documentation text normalized.
assignedSongData = pendingSongData;
assignedDifficulty = pendingDifficulty;
// Խֻ
// Documentation text normalized.
bool ok = LoadBeatmapFromSongData(assignedSongData, assignedDifficulty, true);
if (!ok) Debug.LogWarning("BeatmapManager.Start: LoadBeatmapFromSongData failed");
else
@@ -389,20 +400,20 @@ public class BeatmapManager : MonoBehaviour
pendingDifficulty = -1;
}
// ڲģʽԶ
// Documentation text normalized.
if (GameConfig.testMode)
{
Debug.Log("Test mode active: skipping automatic beatmap load in BeatmapManager.Start");
}
else
{
// ԭĬϼصĵעͣΪҪʱֶָ
// LoadBeatmap("Emilia_demo.json"); // زʵ
// Documentation text normalized.
// Documentation text normalized.
Debug.LogWarning("Default automatic demo beatmap load is commented out to prioritize SO-provided charts.");
}
}
// ȡǰѶȳ
// Documentation text normalized.
private float GetCurrentDifficultyMultiplier()
{
if (parsedDifficulty == 1) return ezMultiplier;
@@ -412,7 +423,26 @@ public class BeatmapManager : MonoBehaviour
return 1f;
}
// ͳһ ID ȡ͸ UI Լ HP ߼
private void SyncEnemyListToUI()
{
if (uiController == null) return;
List<int> enemyIds = new List<int>();
// 优先从 SO 读取
if (assignedSongData != null && assignedSongData.enemyList != null && assignedSongData.enemyList.Count > 0)
{
enemyIds = new List<int>(assignedSongData.enemyList);
}
// 确保 5 个槽位:截断或补 0
while (enemyIds.Count < 5) enemyIds.Add(0);
if (enemyIds.Count > 5) enemyIds = enemyIds.GetRange(0, 5);
uiController.enemySlotIds = enemyIds;
Debug.Log($"[BeatmapManager] SyncEnemyListToUI: {string.Join(",", enemyIds)}");
}
private void SetupEnemiesAndHP()
{
if (uiController == null)
@@ -421,9 +451,17 @@ public class BeatmapManager : MonoBehaviour
return;
}
if (!parsedEnemyListIsEmpty && parsedColorSegments != null && parsedColorSegments.Length > 0)
List<int> enemyIds = new List<int>();
// 优先使用 SongData SO 中配置的敌人列表
if (assignedSongData != null && assignedSongData.enemyList != null && assignedSongData.enemyList.Count > 0)
{
enemyIds = new List<int>(assignedSongData.enemyList);
Debug.Log($"[BeatmapManager] Using enemyList from SongData SO: {string.Join(",", enemyIds)}");
}
// 如果 SO 中没有,则尝试从谱面 JSON 解析
else if (!parsedEnemyListIsEmpty && parsedColorSegments != null && parsedColorSegments.Length > 0)
{
List<int> enemyIds = new List<int>();
foreach (var segment in parsedColorSegments)
{
Debug.Log($"Processing colorSegment: enemyID='{segment.enemyID}', percentage={segment.percentage}");
@@ -435,33 +473,29 @@ public class BeatmapManager : MonoBehaviour
}
enemyIds.Add(enemyId);
}
while (enemyIds.Count < 5) enemyIds.Add(0);
Debug.Log($"Assigning enemySlotIds to teamUIController: {string.Join(",", enemyIds)}");
uiController.enemySlotIds = enemyIds;
uiController.PopulateEnemySOsFromIds();
if (parsedNoteAmount > 0)
{
float currentMultiplier = GetCurrentDifficultyMultiplier();
float totalCalculatedHP = parsedNoteAmount * currentMultiplier * baseHpUnitScale;
int activeEnemyCount = enemyIds.FindAll(id => id != 0).Count;
if (activeEnemyCount == 0) activeEnemyCount = 1;
int individualMaxHP = Mathf.RoundToInt(totalCalculatedHP / activeEnemyCount);
Debug.Log($"[BeatmapManager] HP Calc -> Notes: {parsedNoteAmount}, Multiplier: {currentMultiplier}, Total: {totalCalculatedHP:F0}, ActiveEnemies: {activeEnemyCount}, Per Enemy: {individualMaxHP}");
uiController.ApplyCalculatedEnemyHP(individualMaxHP);
}
Debug.Log($"[BeatmapManager] Using enemyList from Beatmap JSON: {string.Join(",", enemyIds)}");
}
else
// 确保列表始终为 5 个槽位
while (enemyIds.Count < 5) enemyIds.Add(0);
if (enemyIds.Count > 5) enemyIds = enemyIds.GetRange(0, 5);
uiController.enemySlotIds = enemyIds;
uiController.PopulateEnemySOsFromIds();
if (parsedNoteAmount > 0)
{
Debug.Log("Parsed enemy list is empty, clearing UI.");
uiController.enemySlotIds = new List<int> { 0, 0, 0, 0, 0 };
uiController.PopulateEnemySOsFromIds();
float currentMultiplier = GetCurrentDifficultyMultiplier();
float totalCalculatedHP = parsedNoteAmount * currentMultiplier * baseHpUnitScale;
int activeEnemyCount = enemyIds.FindAll(id => id != 0).Count;
if (activeEnemyCount == 0) activeEnemyCount = 1;
int individualMaxHP = Mathf.RoundToInt(totalCalculatedHP / activeEnemyCount);
Debug.Log($"[BeatmapManager] HP Calc -> Notes: {parsedNoteAmount}, Multiplier: {currentMultiplier}, Total: {totalCalculatedHP:F0}, ActiveEnemies: {activeEnemyCount}, Per Enemy: {individualMaxHP}");
uiController.ApplyCalculatedEnemyHP(individualMaxHP);
}
}
@@ -481,13 +515,13 @@ public class BeatmapManager : MonoBehaviour
}
catch (System.Exception ex)
{
Debug.LogError($" Beatmap ʧ: {ex}");
Debug.LogError($"解析 Beatmap 失败: {ex}");
return;
}
if (parsed == null)
{
Debug.LogError(" Beatmap null");
Debug.LogError("解析 Beatmap 结果为 null");
return;
}
@@ -543,10 +577,10 @@ public class BeatmapManager : MonoBehaviour
// Ensure amount and color statistics are populated even if missing from JSON
ValidateAndPopulateStatistics(parsed);
CalculateNoteScores();
CalculateNoteScores(parsed);
beatmap = parsed;
Debug.Log("Ѽأ" + beatmap.title);
Debug.Log("谱面加载完成: " + beatmap.title);
if (noteSpawner != null) noteSpawner.LoadBeatmap(beatmap);
else Debug.LogError("NoteSpawner is null in BeatmapManager.");
@@ -554,13 +588,31 @@ public class BeatmapManager : MonoBehaviour
SetupEnemiesAndHP();
}
private void CalculateNoteScores()
private int GetEffectiveNoteCount(Beatmap sourceBeatmap = null)
{
if (parsedNoteAmount > 0)
int noteCount = 0;
var src = sourceBeatmap != null ? sourceBeatmap : beatmap;
if (src != null && src.notes != null)
noteCount = src.notes.Length;
if (noteCount <= 0)
noteCount = Mathf.Max(0, parsedNoteAmount);
if (noteCount > 0)
parsedNoteAmount = noteCount;
return noteCount;
}
private void CalculateNoteScores(Beatmap sourceBeatmap = null)
{
int noteCount = GetEffectiveNoteCount(sourceBeatmap);
if (noteCount > 0)
{
perNoteScore = totalChartScore / parsedNoteAmount;
leftoverScore = totalChartScore % parsedNoteAmount;
Debug.Log($"Calculated perNoteScore: {perNoteScore}, leftoverScore: {leftoverScore}");
perNoteScore = totalChartScore / noteCount;
leftoverScore = totalChartScore % noteCount;
Debug.Log($"Calculated perNoteScore: {perNoteScore}, leftoverScore: {leftoverScore}, noteCount: {noteCount}");
}
else
{
@@ -618,9 +670,10 @@ public class BeatmapManager : MonoBehaviour
counts[idx]++;
}
int effectiveNoteCount = GetEffectiveNoteCount(parsed);
int per = perNoteScore;
if (per <= 0 && parsedNoteAmount > 0)
per = totalChartScore / parsedNoteAmount;
if (per <= 0 && effectiveNoteCount > 0)
per = totalChartScore / effectiveNoteCount;
var ui = teamUIController.Instance;
for (int i = 0; i < trackCount; i++)