233 lines
7.8 KiB
C#
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.");
|
|
}
|
|
}
|