修了不少东西
This commit is contained in:
@@ -9,6 +9,9 @@ using UnityEditor;
|
||||
[CreateAssetMenu(fileName = "NewAllyHero", menuName = "SO_Data/AllyHero")]
|
||||
public class AllyHero_SO : ScriptableObject
|
||||
{
|
||||
private const string EquippedEquipmentSaveCategory = "ally_equipped_equipment";
|
||||
private const string EquippedEquipmentRecoverySlotPrefix = "ally_equipped_equipment_";
|
||||
|
||||
public static readonly string[] BehaviourAxisNames =
|
||||
{
|
||||
"题海战术",
|
||||
@@ -154,6 +157,13 @@ public class AllyHero_SO : ScriptableObject
|
||||
public equipmentSO equippedEquipment;
|
||||
public string equippedEquipmentId;
|
||||
|
||||
// 【性能】装备存档已从磁盘水合过一次的标记。水合后内存即权威来源:
|
||||
// SetEquippedEquipment / ApplyEquippedEquipmentPayload / ClearEquippedEquipment 都会同步更新内存与磁盘,
|
||||
// 因此无需反复解密读盘。idols 界面每次切换角色时 RebuildBag 会对"每件装备 × 每个英雄"调用
|
||||
// LoadEquippedEquipmentFromLocal 做占用检查,若每次都真正解密 SecureSaveVault 会造成严重卡顿。
|
||||
// 该标记确保每个英雄整个会话只读盘一次,之后走内存,行为完全不变。
|
||||
[System.NonSerialized] private bool equippedEquipmentHydrated;
|
||||
|
||||
public SkillDefinition GetPrimarySkill()
|
||||
{
|
||||
if (availableSkills == null || primarySkillIndex < 0 || primarySkillIndex >= availableSkills.Length) return null;
|
||||
@@ -506,12 +516,14 @@ public class AllyHero_SO : ScriptableObject
|
||||
{
|
||||
List<AllyLevelInfo> sorted = BuildSortedLevelStats();
|
||||
int unlockedIndex = ResolveUnlockedLevelIndex(sorted);
|
||||
if (unlockedIndex < 0 || unlockedIndex >= sorted.Count)
|
||||
int expQualifiedIndex = ResolveExpQualifiedLevelIndex(sorted);
|
||||
if (unlockedIndex < 0 || expQualifiedIndex < 0 || sorted == null || sorted.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return sorted[unlockedIndex];
|
||||
int effectiveIndex = Mathf.Clamp(Mathf.Min(expQualifiedIndex, unlockedIndex), 0, sorted.Count - 1);
|
||||
return sorted[effectiveIndex];
|
||||
}
|
||||
|
||||
private List<AllyLevelInfo> BuildSortedLevelStats()
|
||||
@@ -702,6 +714,16 @@ public class AllyHero_SO : ScriptableObject
|
||||
return "ally_equippedEquipment_" + ally_heroID;
|
||||
}
|
||||
|
||||
private string GetEquippedEquipmentSaveKey()
|
||||
{
|
||||
return ally_heroID.ToString();
|
||||
}
|
||||
|
||||
private string GetEquippedEquipmentRecoverySlotKey()
|
||||
{
|
||||
return EquippedEquipmentRecoverySlotPrefix + ally_heroID;
|
||||
}
|
||||
|
||||
private string GetSelectedSkinPrefsKey()
|
||||
{
|
||||
return "ally_selectedSkin_" + ally_heroID;
|
||||
@@ -731,13 +753,39 @@ public class AllyHero_SO : ScriptableObject
|
||||
equippedEquipmentId = equippedEquipment != null ? equippedEquipment.name : string.Empty;
|
||||
var payload = new EquippedEquipmentPayload { equippedEquipmentId = equippedEquipmentId ?? string.Empty };
|
||||
string json = JsonUtility.ToJson(payload);
|
||||
SecureSaveVault.SaveJson(EquippedEquipmentSaveCategory, GetEquippedEquipmentSaveKey(), payload);
|
||||
LocalRecoveryMirror.SaveJson(GetEquippedEquipmentRecoverySlotKey(), payload);
|
||||
PlayerPrefs.SetString(GetEquippedEquipmentPrefsKey(), json);
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
public void LoadEquippedEquipmentFromLocal()
|
||||
public void LoadEquippedEquipmentFromLocal(bool forceReload = false)
|
||||
{
|
||||
// 已水合且非强制刷新时直接返回,避免重复解密读盘(见 equippedEquipmentHydrated 说明)。
|
||||
if (equippedEquipmentHydrated && !forceReload)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 无论后续走哪条分支,本次调用都视为已完成水合:
|
||||
// 命中存档→内存已填充;无存档→内存保持当前值,也不必反复重试读盘。
|
||||
equippedEquipmentHydrated = true;
|
||||
|
||||
string key = GetEquippedEquipmentPrefsKey();
|
||||
EquippedEquipmentPayload payload;
|
||||
if (SecureSaveVault.TryLoadJson(EquippedEquipmentSaveCategory, GetEquippedEquipmentSaveKey(), out payload) && payload != null)
|
||||
{
|
||||
ApplyEquippedEquipmentPayload(payload);
|
||||
return;
|
||||
}
|
||||
|
||||
if (LocalRecoveryMirror.TryLoadJson(GetEquippedEquipmentRecoverySlotKey(), out payload) && payload != null)
|
||||
{
|
||||
ApplyEquippedEquipmentPayload(payload);
|
||||
SecureSaveVault.SaveJson(EquippedEquipmentSaveCategory, GetEquippedEquipmentSaveKey(), payload);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PlayerPrefs.HasKey(key))
|
||||
{
|
||||
return;
|
||||
@@ -749,7 +797,19 @@ public class AllyHero_SO : ScriptableObject
|
||||
return;
|
||||
}
|
||||
|
||||
EquippedEquipmentPayload payload = JsonUtility.FromJson<EquippedEquipmentPayload>(json);
|
||||
payload = JsonUtility.FromJson<EquippedEquipmentPayload>(json);
|
||||
if (payload == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyEquippedEquipmentPayload(payload);
|
||||
SecureSaveVault.SaveJson(EquippedEquipmentSaveCategory, GetEquippedEquipmentSaveKey(), payload);
|
||||
LocalRecoveryMirror.SaveJson(GetEquippedEquipmentRecoverySlotKey(), payload);
|
||||
}
|
||||
|
||||
private void ApplyEquippedEquipmentPayload(EquippedEquipmentPayload payload)
|
||||
{
|
||||
if (payload == null)
|
||||
{
|
||||
return;
|
||||
@@ -763,6 +823,7 @@ public class AllyHero_SO : ScriptableObject
|
||||
{
|
||||
equippedEquipment = equipment;
|
||||
equippedEquipmentId = equipment != null ? equipment.name : string.Empty;
|
||||
equippedEquipmentHydrated = true;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
@@ -801,6 +862,9 @@ public class AllyHero_SO : ScriptableObject
|
||||
{
|
||||
equippedEquipment = null;
|
||||
equippedEquipmentId = string.Empty;
|
||||
equippedEquipmentHydrated = true;
|
||||
SecureSaveVault.Delete(EquippedEquipmentSaveCategory, GetEquippedEquipmentSaveKey());
|
||||
LocalRecoveryMirror.DeleteSlot(GetEquippedEquipmentRecoverySlotKey());
|
||||
PlayerPrefs.DeleteKey(GetEquippedEquipmentPrefsKey());
|
||||
PlayerPrefs.Save();
|
||||
#if UNITY_EDITOR
|
||||
|
||||
Reference in New Issue
Block a user