Files
bansonic_beta_main/Assets/scripts/InGameAchievements/InGamePerformanceManager.cs
T
2026-07-20 22:19:25 +08:00

233 lines
7.8 KiB
C#

using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class InGamePerformanceManager : MonoBehaviour
{
public static InGamePerformanceManager Instance { get; private set; }
public int HighestComboThisRun { get; private set; }
[Header("Inspector")]
[Tooltip("Achievement definitions loaded from Resources.")]
[SerializeField] private List<InGameAchievementSO> achievementLibrary = new List<InGameAchievementSO>();
[Header("Inspector")]
public GameObject archievePrefab;
public GameObject place_to_putdown;
[System.Serializable]
public class CategoryDisplayMapping
{
public AchievementCategory category;
public GameObject parent;
}
public List<CategoryDisplayMapping> categoryDisplays = new List<CategoryDisplayMapping>();
private class UnlockedAchievementInfo
{
public AchievementLevel level;
public InGameAchievementSO sourceSO;
}
private readonly Dictionary<AchievementCategory, UnlockedAchievementInfo> unlockedAchievements =
new Dictionary<AchievementCategory, UnlockedAchievementInfo>();
private void Awake()
{
if (Instance == null)
{
Instance = this;
HighestComboThisRun = 0;
LoadAchievementLibrary();
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
// 如果开启了自动打击模式,直接授予 Autoplay 成就
if (GameConfig.autoPlayEnabled)
{
CheckAutoplayAchievement();
}
}
private void CheckAutoplayAchievement()
{
// 查找属于 Autoplay 分类的配置
var autoplaySO = achievementLibrary.FirstOrDefault(a => a != null && a.category == AchievementCategory.Autoplay);
if (autoplaySO != null && autoplaySO.levels != null && autoplaySO.levels.Count > 0)
{
// 自动打击模式下,直接解锁该分类下的第一个等级(观赏模式成就)
var level = autoplaySO.levels[0];
unlockedAchievements.Clear(); // 确保排他性:只保留这一个成就
unlockedAchievements.Add(AchievementCategory.Autoplay, new UnlockedAchievementInfo
{
level = level,
sourceSO = autoplaySO
});
Debug.Log("<color=yellow>[PerformanceManager] 自动打击模式已开启:锁定 Autoplay 成就,禁用其他成就。</color>");
}
}
private void LoadAchievementLibrary()
{
achievementLibrary.Clear();
var loaded = Resources.LoadAll<InGameAchievementSO>("Achievements");
if (loaded == null || loaded.Length == 0)
loaded = Resources.LoadAll<InGameAchievementSO>(string.Empty);
if (loaded == null || loaded.Length == 0)
{
Debug.LogError("[PerformanceManager] No InGameAchievementSO found under Resources.");
return;
}
for (int i = 0; i < loaded.Length; i++)
{
var so = loaded[i];
if (so != null && !achievementLibrary.Contains(so))
achievementLibrary.Add(so);
}
Debug.Log($"[PerformanceManager] Loaded {achievementLibrary.Count} achievement categories.");
}
public void UpdateCombo(int currentCombo)
{
if (currentCombo > HighestComboThisRun)
{
HighestComboThisRun = currentCombo;
}
CheckAchievementsByCategory(AchievementCategory.Combo, currentCombo);
}
public void UpdateTotalCure(float totalCure)
{
CheckAchievementsByCategory(AchievementCategory.TotalCure, totalCure);
}
public void UpdateTotalDamage(float totalDamage)
{
CheckAchievementsByCategory(AchievementCategory.TotalDamage, totalDamage);
}
public void UpdateTotalManaRestored(float totalMana)
{
CheckAchievementsByCategory(AchievementCategory.TotalManaRestored, totalMana);
}
public void UpdateTotalScore(float totalScore)
{
CheckAchievementsByCategory(AchievementCategory.TotalScore, totalScore);
}
private void CheckAchievementsByCategory(AchievementCategory category, float currentValue)
{
// 如果开启了自动打击模式,禁止获得除 Autoplay 以外的任何成就
if (GameConfig.autoPlayEnabled)
{
if (category != AchievementCategory.Autoplay)
return;
}
if (achievementLibrary == null || achievementLibrary.Count == 0)
return;
var categorySOs = achievementLibrary.Where(a => a != null && a.category == category);
foreach (var categorySO in categorySOs)
{
if (categorySO.levels == null || categorySO.levels.Count == 0)
continue;
var bestLevelForThisSO = categorySO.levels
.Where(l => l != null && currentValue >= l.triggerValue)
.OrderByDescending(l => l.triggerValue)
.FirstOrDefault();
if (bestLevelForThisSO == null)
continue;
if (unlockedAchievements.TryGetValue(category, out var existingInfo))
{
if (existingInfo == null || existingInfo.level == null || bestLevelForThisSO.triggerValue > existingInfo.level.triggerValue)
{
unlockedAchievements[category] = new UnlockedAchievementInfo
{
level = bestLevelForThisSO,
sourceSO = categorySO
};
}
}
else
{
unlockedAchievements.Add(category, new UnlockedAchievementInfo
{
level = bestLevelForThisSO,
sourceSO = categorySO
});
}
}
}
public void LoadArchievePrefab()
{
if (archievePrefab == null)
{
Debug.LogWarning("[PerformanceManager] archievePrefab is not assigned.");
return;
}
if (place_to_putdown != null)
{
foreach (Transform child in place_to_putdown.transform)
Destroy(child.gameObject);
}
for (int i = 0; i < categoryDisplays.Count; i++)
{
var mapping = categoryDisplays[i];
if (mapping != null && mapping.parent != null)
{
foreach (Transform child in mapping.parent.transform)
Destroy(child.gameObject);
}
}
var sortedAchievements = unlockedAchievements.Values
.Where(v => v != null && v.level != null)
.OrderByDescending(info => (int)info.level.rarity)
.ToList();
for (int i = 0; i < sortedAchievements.Count; i++)
{
var info = sortedAchievements[i];
var cat = info.sourceSO != null ? info.sourceSO.category : AchievementCategory.Combo;
GameObject targetParent = place_to_putdown;
var mapping = categoryDisplays.FirstOrDefault(m => m != null && m.category == cat && m.parent != null);
if (mapping != null && mapping.parent != null)
targetParent = mapping.parent;
if (targetParent == null)
continue;
GameObject prefabToSpawn = (info.sourceSO != null && info.sourceSO.customPrefab != null) ? info.sourceSO.customPrefab : archievePrefab;
GameObject go = Instantiate(prefabToSpawn, targetParent.transform);
UI_OrderedEntryAnimator.PlayFadeOnly(go, i, 0.16f, 0.012f, true);
var script = go.GetComponent<archievePrefab>();
if (script != null)
script.Setup(info.level);
}
Debug.Log($"[PerformanceManager] Spawned {sortedAchievements.Count} achievement cards.");
}
}