超大量的更新 修复很多问题,gameplay特效初步
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public enum AchievementRarity
|
||||
{
|
||||
Common, // 普通 (白)
|
||||
Advanced, // 进阶 (绿)
|
||||
Rare, // 卓越 (蓝)
|
||||
Epic, // 史诗 (紫)
|
||||
Legendary, // 传说 (金)
|
||||
Mythic, // 神话 (红)
|
||||
Exquisite // 至臻 (彩)
|
||||
Common,
|
||||
Advanced,
|
||||
Rare,
|
||||
Epic,
|
||||
Legendary,
|
||||
Mythic,
|
||||
Exquisite
|
||||
}
|
||||
|
||||
public enum AchievementCategory
|
||||
@@ -17,28 +18,29 @@ public enum AchievementCategory
|
||||
TotalCure, // 治疗总量
|
||||
TotalDamage, // 伤害总量
|
||||
TotalManaRestored, // 法力恢复总量
|
||||
TotalScore // 总分数
|
||||
TotalScore,
|
||||
Autoplay // 自动打击/观赏模式
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class AchievementLevel
|
||||
{
|
||||
public string levelName; // 等级名称 (例如: 50连击)
|
||||
public float triggerValue; // 触发数值
|
||||
public AchievementRarity rarity; // 稀有度
|
||||
public string description; // 详情介绍 (一行文本)
|
||||
public Sprite icon; // 图标
|
||||
public string levelName;
|
||||
public float triggerValue;
|
||||
public string description;
|
||||
public Sprite icon;
|
||||
public AchievementRarity rarity = AchievementRarity.Common;
|
||||
}
|
||||
|
||||
[CreateAssetMenu(fileName = "NewAchievementCategory", menuName = "EaseOut/Achievement Category")]
|
||||
public class InGameAchievementSO : ScriptableObject
|
||||
{
|
||||
[Header("分类信息")]
|
||||
public string achievementID; // 成就编号
|
||||
public string achievementType; // 成就类型 (string)
|
||||
[Header("Inspector")]
|
||||
public string achievementID;
|
||||
public string achievementType;
|
||||
public AchievementCategory category;
|
||||
public GameObject customPrefab; // 该分类特有的预制体 (可选)
|
||||
|
||||
[Header("成就等级列表")]
|
||||
public System.Collections.Generic.List<AchievementLevel> levels = new System.Collections.Generic.List<AchievementLevel>();
|
||||
public GameObject customPrefab;
|
||||
|
||||
[Header("Inspector")]
|
||||
public List<AchievementLevel> levels = new List<AchievementLevel>();
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class InGamePerformanceManager : MonoBehaviour
|
||||
{
|
||||
public static InGamePerformanceManager Instance { get; private set; }
|
||||
|
||||
[Header("成就库")]
|
||||
[Tooltip("在 Resources/Achievements 目录下的所有成就资源")]
|
||||
private List<InGameAchievementSO> achievementLibrary = new List<InGameAchievementSO>();
|
||||
[Header("Inspector")]
|
||||
[Tooltip("Achievement definitions loaded from Resources.")]
|
||||
[SerializeField] private List<InGameAchievementSO> achievementLibrary = new List<InGameAchievementSO>();
|
||||
|
||||
[Header("结算展示配置")]
|
||||
public GameObject archievePrefab; // 通用成就预制体
|
||||
public GameObject place_to_putdown; // 默认实例化容器
|
||||
[Header("Inspector")]
|
||||
public GameObject archievePrefab;
|
||||
public GameObject place_to_putdown;
|
||||
|
||||
[System.Serializable]
|
||||
public class CategoryDisplayMapping
|
||||
@@ -20,20 +20,20 @@ public class InGamePerformanceManager : MonoBehaviour
|
||||
public AchievementCategory category;
|
||||
public GameObject parent;
|
||||
}
|
||||
|
||||
public List<CategoryDisplayMapping> categoryDisplays = new List<CategoryDisplayMapping>();
|
||||
|
||||
// 记录每个分类下达成的最高成就及其来源 SO
|
||||
private class UnlockedAchievementInfo
|
||||
{
|
||||
public AchievementLevel level;
|
||||
public InGameAchievementSO sourceSO;
|
||||
}
|
||||
|
||||
private Dictionary<AchievementCategory, UnlockedAchievementInfo> unlockedAchievements = new Dictionary<AchievementCategory, UnlockedAchievementInfo>();
|
||||
private readonly Dictionary<AchievementCategory, UnlockedAchievementInfo> unlockedAchievements =
|
||||
new Dictionary<AchievementCategory, UnlockedAchievementInfo>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Debug.Log("[PerformanceManager] Awake called");
|
||||
if (Instance == null)
|
||||
{
|
||||
Instance = this;
|
||||
@@ -45,197 +45,179 @@ public class InGamePerformanceManager : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadAchievementLibrary()
|
||||
private void Start()
|
||||
{
|
||||
// 尝试从 Resources/Achievements 加载
|
||||
var loaded = Resources.LoadAll<InGameAchievementSO>("Achievements");
|
||||
|
||||
// 如果根目录没找到,尝试在整个 Resources 中搜索
|
||||
if (loaded == null || loaded.Length == 0)
|
||||
// 如果开启了自动打击模式,直接授予 Autoplay 成就
|
||||
if (GameConfig.autoPlayEnabled)
|
||||
{
|
||||
loaded = Resources.LoadAll<InGameAchievementSO>("");
|
||||
}
|
||||
|
||||
if (loaded != null && loaded.Length > 0)
|
||||
{
|
||||
achievementLibrary.Clear();
|
||||
// 过滤掉可能重复加载的 SO(如果是在根目录搜索)
|
||||
foreach (var so in loaded)
|
||||
{
|
||||
if (!achievementLibrary.Contains(so))
|
||||
achievementLibrary.Add(so);
|
||||
}
|
||||
Debug.Log($"[PerformanceManager] 扫描成功!已加载 {achievementLibrary.Count} 个分类配置文件");
|
||||
|
||||
foreach (var a in achievementLibrary)
|
||||
{
|
||||
Debug.Log($" - 分类: {a.category} (ID: {a.achievementID}, Type: {a.achievementType}), 包含 {a.levels.Count} 个等级");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[PerformanceManager] 关键错误:未在 Resources 路径下找到任何 InGameAchievementSO 资源!请确保 SO 文件位于 Resources 文件夹内。");
|
||||
CheckAutoplayAchievement();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新当前 Combo 数并检查相关成就
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
Debug.Log($"[PerformanceManager] UpdateCombo called with: {currentCombo}");
|
||||
CheckAchievementsByCategory(AchievementCategory.Combo, currentCombo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新本局治疗总量并检查成就
|
||||
/// </summary>
|
||||
public void UpdateTotalCure(float totalCure)
|
||||
{
|
||||
Debug.Log($"[PerformanceManager] UpdateTotalCure called with: {totalCure}");
|
||||
CheckAchievementsByCategory(AchievementCategory.TotalCure, totalCure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新本局伤害总量并检查成就
|
||||
/// </summary>
|
||||
public void UpdateTotalDamage(float totalDamage)
|
||||
{
|
||||
Debug.Log($"[PerformanceManager] UpdateTotalDamage called with: {totalDamage}");
|
||||
CheckAchievementsByCategory(AchievementCategory.TotalDamage, totalDamage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新本局法力恢复总量并检查成就
|
||||
/// </summary>
|
||||
public void UpdateTotalManaRestored(float totalMana)
|
||||
{
|
||||
Debug.Log($"[PerformanceManager] UpdateTotalManaRestored called with: {totalMana}");
|
||||
CheckAchievementsByCategory(AchievementCategory.TotalManaRestored, totalMana);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新本局总分数并检查成就
|
||||
/// </summary>
|
||||
public void UpdateTotalScore(float totalScore)
|
||||
{
|
||||
Debug.Log($"[PerformanceManager] UpdateTotalScore called with: {totalScore}");
|
||||
CheckAchievementsByCategory(AchievementCategory.TotalScore, totalScore);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通用的成就检测逻辑
|
||||
/// </summary>
|
||||
private void CheckAchievementsByCategory(AchievementCategory category, float currentValue)
|
||||
{
|
||||
// 如果开启了自动打击模式,禁止获得除 Autoplay 以外的任何成就
|
||||
if (GameConfig.autoPlayEnabled)
|
||||
{
|
||||
if (category != AchievementCategory.Autoplay)
|
||||
return;
|
||||
}
|
||||
|
||||
if (achievementLibrary == null || achievementLibrary.Count == 0)
|
||||
{
|
||||
Debug.LogWarning($"[PerformanceManager] Achievement library is empty! Cannot check category: {category}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 查找所有属于该逻辑分类的 SO 配置
|
||||
var matchingCategories = achievementLibrary.Where(a => a.category == category).ToList();
|
||||
|
||||
if (matchingCategories.Count == 0)
|
||||
var categorySOs = achievementLibrary.Where(a => a != null && a.category == category);
|
||||
foreach (var categorySO in categorySOs)
|
||||
{
|
||||
Debug.LogWarning($"[PerformanceManager] No matching SO found for category: {category}. Library size: {achievementLibrary.Count}");
|
||||
return;
|
||||
}
|
||||
if (categorySO.levels == null || categorySO.levels.Count == 0)
|
||||
continue;
|
||||
|
||||
foreach (var categorySO in matchingCategories)
|
||||
{
|
||||
// 找出该 SO 下满足条件的最高等级
|
||||
AchievementLevel bestLevelForThisSO = categorySO.levels
|
||||
.Where(l => currentValue >= l.triggerValue)
|
||||
var bestLevelForThisSO = categorySO.levels
|
||||
.Where(l => l != null && currentValue >= l.triggerValue)
|
||||
.OrderByDescending(l => l.triggerValue)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (bestLevelForThisSO != null)
|
||||
if (bestLevelForThisSO == null)
|
||||
continue;
|
||||
|
||||
if (unlockedAchievements.TryGetValue(category, out var existingInfo))
|
||||
{
|
||||
// 检查该分类是否已经记录过成就
|
||||
if (unlockedAchievements.TryGetValue(category, out var existingInfo))
|
||||
if (existingInfo == null || existingInfo.level == null || bestLevelForThisSO.triggerValue > existingInfo.level.triggerValue)
|
||||
{
|
||||
// 如果当前 SO 达成的等级数值比已记录的更高,则更新
|
||||
if (bestLevelForThisSO.triggerValue > existingInfo.level.triggerValue)
|
||||
unlockedAchievements[category] = new UnlockedAchievementInfo
|
||||
{
|
||||
existingInfo.level = bestLevelForThisSO;
|
||||
existingInfo.sourceSO = categorySO;
|
||||
Debug.Log($"<color=green>[PerformanceManager] 分类 {category} 成就升级: {bestLevelForThisSO.levelName}</color>");
|
||||
}
|
||||
level = bestLevelForThisSO,
|
||||
sourceSO = categorySO
|
||||
};
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
unlockedAchievements.Add(category, new UnlockedAchievementInfo
|
||||
{
|
||||
// 该分类第一次达成成就
|
||||
unlockedAchievements.Add(category, new UnlockedAchievementInfo
|
||||
{
|
||||
level = bestLevelForThisSO,
|
||||
sourceSO = categorySO
|
||||
});
|
||||
Debug.Log($"<color=cyan>[PerformanceManager] 分类 {category} 达成新成就: {bestLevelForThisSO.levelName}</color>");
|
||||
}
|
||||
level = bestLevelForThisSO,
|
||||
sourceSO = categorySO
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在结算界面实例化成就 UI
|
||||
/// </summary>
|
||||
public void LoadArchievePrefab()
|
||||
{
|
||||
if (archievePrefab == null)
|
||||
{
|
||||
Debug.LogWarning("[PerformanceManager] 无法实例化成就:通用预制体为空");
|
||||
Debug.LogWarning("[PerformanceManager] archievePrefab is not assigned.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 清空所有已配置的容器
|
||||
if (place_to_putdown != null)
|
||||
{
|
||||
foreach (Transform child in place_to_putdown.transform) Destroy(child.gameObject);
|
||||
foreach (Transform child in place_to_putdown.transform)
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
foreach (var mapping in categoryDisplays)
|
||||
|
||||
for (int i = 0; i < categoryDisplays.Count; i++)
|
||||
{
|
||||
if (mapping.parent != null)
|
||||
var mapping = categoryDisplays[i];
|
||||
if (mapping != null && mapping.parent != null)
|
||||
{
|
||||
foreach (Transform child in mapping.parent.transform) Destroy(child.gameObject);
|
||||
foreach (Transform child in mapping.parent.transform)
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 按稀有度排序并实例化
|
||||
var sortedAchievements = unlockedAchievements.Values
|
||||
.Where(v => v != null && v.level != null)
|
||||
.OrderByDescending(info => (int)info.level.rarity)
|
||||
.ToList();
|
||||
|
||||
foreach (var info in sortedAchievements)
|
||||
{
|
||||
// 确定父物体:如果在映射表里找到了对应的 category,就用它的 parent;否则用默认的 place_to_putdown
|
||||
var cat = info.sourceSO != null ? info.sourceSO.category : AchievementCategory.Combo;
|
||||
GameObject targetParent = place_to_putdown;
|
||||
|
||||
// 注意:info.sourceSO 可能为空(防御性编程),所以先检查
|
||||
AchievementCategory cat = info.sourceSO != null ? info.sourceSO.category : AchievementCategory.Combo;
|
||||
|
||||
var mapping = categoryDisplays.FirstOrDefault(m => m.category == cat);
|
||||
|
||||
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)
|
||||
{
|
||||
Debug.LogWarning($"[PerformanceManager] 分类 {cat} 没有可用的父容器 (默认容器也为空)");
|
||||
continue;
|
||||
}
|
||||
|
||||
// 实例化通用预制体
|
||||
GameObject go = Instantiate(archievePrefab, targetParent.transform);
|
||||
GameObject prefabToSpawn = (info.sourceSO != null && info.sourceSO.customPrefab != null) ? info.sourceSO.customPrefab : archievePrefab;
|
||||
GameObject go = Instantiate(prefabToSpawn, targetParent.transform);
|
||||
|
||||
var script = go.GetComponent<archievePrefab>();
|
||||
if (script != null)
|
||||
{
|
||||
script.Setup(info.level);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Log($"[PerformanceManager] 已在结算页面实例化 {sortedAchievements.Count} 个成就");
|
||||
|
||||
Debug.Log($"[PerformanceManager] Spawned {sortedAchievements.Count} achievement cards.");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user