装备系统完结,修复并加入很多
This commit is contained in:
+358
-40
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Bansonic;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
@@ -10,15 +12,81 @@ using UnityEditor;
|
||||
|
||||
public class equipBag : MonoBehaviour
|
||||
{
|
||||
private enum EquipFilterMode
|
||||
{
|
||||
All,
|
||||
HasSpecialSkill,
|
||||
HasIllusionSkill,
|
||||
HasAnySkill,
|
||||
HasNoSkill,
|
||||
HasDualSkill,
|
||||
Type0,
|
||||
Type1,
|
||||
Type2,
|
||||
Type3,
|
||||
Type4,
|
||||
Type5,
|
||||
Type6,
|
||||
Type7
|
||||
}
|
||||
|
||||
private enum EquipOrderMode
|
||||
{
|
||||
AcquireAsc,
|
||||
AcquireDesc,
|
||||
QualityAsc,
|
||||
QualityDesc
|
||||
}
|
||||
|
||||
[Header("prefab")]
|
||||
public GameObject eqpmtItemPrefab;
|
||||
public Transform eqpmtItemParent;
|
||||
|
||||
[Header("dropdown")]
|
||||
public Dropdown orderDropdown;
|
||||
public Dropdown filterDropdown;
|
||||
|
||||
[Header("source paths")]
|
||||
public string runtimeEquipmentFolder = "so/uEquip";
|
||||
public string editorEquipmentFolder = "Assets/Resources/so/uEquip";
|
||||
|
||||
[Header("async spawn")]
|
||||
public int spawnBatchSize = 12;
|
||||
|
||||
private readonly List<GameObject> spawnedItems = new List<GameObject>();
|
||||
private Coroutine rebuildCoroutine;
|
||||
private bool suppressDropdownCallbacks;
|
||||
|
||||
private static readonly (EquipFilterMode mode, string label)[] FilterOptions =
|
||||
{
|
||||
(EquipFilterMode.All, "全部"),
|
||||
(EquipFilterMode.HasSpecialSkill, "含特效技能"),
|
||||
(EquipFilterMode.HasIllusionSkill, "含巡演技能"),
|
||||
(EquipFilterMode.HasAnySkill, "含技能"),
|
||||
(EquipFilterMode.HasNoSkill, "不含技能"),
|
||||
(EquipFilterMode.HasDualSkill, "含双技能"),
|
||||
(EquipFilterMode.Type0, equipmentSO.EquipmentSkillType.题海战术.ToString()),
|
||||
(EquipFilterMode.Type1, equipmentSO.EquipmentSkillType.诛锄异己.ToString()),
|
||||
(EquipFilterMode.Type2, equipmentSO.EquipmentSkillType.逸乐共谋.ToString()),
|
||||
(EquipFilterMode.Type3, equipmentSO.EquipmentSkillType.完美至上.ToString()),
|
||||
(EquipFilterMode.Type4, equipmentSO.EquipmentSkillType.涵养心境.ToString()),
|
||||
(EquipFilterMode.Type5, equipmentSO.EquipmentSkillType.众志成城.ToString()),
|
||||
(EquipFilterMode.Type6, equipmentSO.EquipmentSkillType.过激行为.ToString()),
|
||||
(EquipFilterMode.Type7, equipmentSO.EquipmentSkillType.二次形变.ToString())
|
||||
};
|
||||
|
||||
private static readonly (EquipOrderMode mode, string label)[] OrderOptions =
|
||||
{
|
||||
(EquipOrderMode.AcquireAsc, "获取时间升序"),
|
||||
(EquipOrderMode.AcquireDesc, "获取时间降序"),
|
||||
(EquipOrderMode.QualityAsc, "品质升序"),
|
||||
(EquipOrderMode.QualityDesc, "品质降序")
|
||||
};
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
InitializeDropdowns();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
@@ -27,11 +95,37 @@ public class equipBag : MonoBehaviour
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
InitializeDropdowns();
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (orderDropdown != null)
|
||||
{
|
||||
orderDropdown.onValueChanged.RemoveListener(HandleOrderChanged);
|
||||
}
|
||||
|
||||
if (filterDropdown != null)
|
||||
{
|
||||
filterDropdown.onValueChanged.RemoveListener(HandleFilterChanged);
|
||||
}
|
||||
|
||||
if (rebuildCoroutine != null)
|
||||
{
|
||||
StopCoroutine(rebuildCoroutine);
|
||||
rebuildCoroutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Rebuild()
|
||||
{
|
||||
if (rebuildCoroutine != null)
|
||||
{
|
||||
StopCoroutine(rebuildCoroutine);
|
||||
rebuildCoroutine = null;
|
||||
}
|
||||
|
||||
ClearSpawnedItems();
|
||||
|
||||
if (eqpmtItemPrefab == null || eqpmtItemParent == null)
|
||||
@@ -39,41 +133,133 @@ public class equipBag : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
equipmentSO[] equipments = LoadEquipments();
|
||||
if (equipments == null || equipments.Length == 0)
|
||||
List<equipmentSO> equipments = LoadEquipments()
|
||||
.Where(equipment => equipment != null
|
||||
&& !equipSmelt.IsEquipmentAssignedToSmeltPool(equipment)
|
||||
&& !equipSmelt.ShouldHideConsumedEquipment(equipment))
|
||||
.Where(MatchesCurrentFilter)
|
||||
.ToList();
|
||||
|
||||
SortEquipments(equipments);
|
||||
|
||||
if (Application.isPlaying && isActiveAndEnabled && gameObject.activeInHierarchy)
|
||||
{
|
||||
rebuildCoroutine = StartCoroutine(RebuildAsync(equipments));
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnAllImmediate(equipments);
|
||||
}
|
||||
|
||||
private void InitializeDropdowns()
|
||||
{
|
||||
InitializeFilterDropdown();
|
||||
InitializeOrderDropdown();
|
||||
}
|
||||
|
||||
private void InitializeFilterDropdown()
|
||||
{
|
||||
if (filterDropdown == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
equipments = equipments
|
||||
.Where(equipment => equipment != null
|
||||
&& !equipSmelt.IsEquipmentAssignedToSmeltPool(equipment)
|
||||
&& !equipSmelt.IsEquipmentConsumedBySmelt(equipment))
|
||||
.ToArray();
|
||||
suppressDropdownCallbacks = true;
|
||||
filterDropdown.onValueChanged.RemoveListener(HandleFilterChanged);
|
||||
filterDropdown.ClearOptions();
|
||||
filterDropdown.AddOptions(FilterOptions.Select(option => new Dropdown.OptionData(option.label)).ToList());
|
||||
filterDropdown.value = 0;
|
||||
filterDropdown.RefreshShownValue();
|
||||
filterDropdown.onValueChanged.AddListener(HandleFilterChanged);
|
||||
suppressDropdownCallbacks = false;
|
||||
}
|
||||
|
||||
Array.Sort(equipments, CompareEquipments);
|
||||
|
||||
for (int i = 0; i < equipments.Length; i++)
|
||||
private void InitializeOrderDropdown()
|
||||
{
|
||||
if (orderDropdown == null)
|
||||
{
|
||||
equipmentSO equipment = equipments[i];
|
||||
if (equipment == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GameObject instance = Instantiate(eqpmtItemPrefab, eqpmtItemParent);
|
||||
instance.name = string.IsNullOrWhiteSpace(equipment.GetCurrentTierDisplayName())
|
||||
? equipment.name
|
||||
: equipment.GetCurrentTierDisplayName();
|
||||
|
||||
equipItemPrefab item = instance.GetComponent<equipItemPrefab>();
|
||||
if (item != null)
|
||||
{
|
||||
item.Bind(equipment, HandleEquipmentClicked);
|
||||
}
|
||||
|
||||
spawnedItems.Add(instance);
|
||||
return;
|
||||
}
|
||||
|
||||
suppressDropdownCallbacks = true;
|
||||
orderDropdown.onValueChanged.RemoveListener(HandleOrderChanged);
|
||||
orderDropdown.ClearOptions();
|
||||
orderDropdown.AddOptions(OrderOptions.Select(option => new Dropdown.OptionData(option.label)).ToList());
|
||||
orderDropdown.value = 0;
|
||||
orderDropdown.RefreshShownValue();
|
||||
orderDropdown.onValueChanged.AddListener(HandleOrderChanged);
|
||||
suppressDropdownCallbacks = false;
|
||||
}
|
||||
|
||||
private void HandleFilterChanged(int _)
|
||||
{
|
||||
if (!suppressDropdownCallbacks)
|
||||
{
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleOrderChanged(int _)
|
||||
{
|
||||
if (!suppressDropdownCallbacks)
|
||||
{
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator RebuildAsync(List<equipmentSO> equipments)
|
||||
{
|
||||
if (equipments == null || equipments.Count == 0)
|
||||
{
|
||||
rebuildCoroutine = null;
|
||||
yield break;
|
||||
}
|
||||
|
||||
int batchSize = Mathf.Max(1, spawnBatchSize);
|
||||
for (int i = 0; i < equipments.Count; i++)
|
||||
{
|
||||
SpawnOne(equipments[i]);
|
||||
|
||||
if ((i + 1) % batchSize == 0)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
rebuildCoroutine = null;
|
||||
}
|
||||
|
||||
private void SpawnAllImmediate(List<equipmentSO> equipments)
|
||||
{
|
||||
if (equipments == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < equipments.Count; i++)
|
||||
{
|
||||
SpawnOne(equipments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnOne(equipmentSO equipment)
|
||||
{
|
||||
if (equipment == null || eqpmtItemPrefab == null || eqpmtItemParent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GameObject instance = Instantiate(eqpmtItemPrefab, eqpmtItemParent);
|
||||
string displayName = equipment.GetDisplayTierName();
|
||||
instance.name = string.IsNullOrWhiteSpace(displayName) ? equipment.name : displayName;
|
||||
|
||||
equipItemPrefab item = instance.GetComponent<equipItemPrefab>();
|
||||
if (item != null)
|
||||
{
|
||||
item.Bind(equipment, HandleEquipmentClicked);
|
||||
}
|
||||
|
||||
spawnedItems.Add(instance);
|
||||
}
|
||||
|
||||
private equipmentSO[] LoadEquipments()
|
||||
@@ -104,9 +290,7 @@ public class equipBag : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
.Where(equipment => equipment != null)
|
||||
.ToArray();
|
||||
return results.Where(equipment => equipment != null).ToArray();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
@@ -119,7 +303,6 @@ public class equipBag : MonoBehaviour
|
||||
|
||||
string[] guids = AssetDatabase.FindAssets("t:equipmentSO", new[] { editorEquipmentFolder });
|
||||
var result = new List<equipmentSO>(guids.Length);
|
||||
|
||||
for (int i = 0; i < guids.Length; i++)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
|
||||
@@ -134,6 +317,75 @@ public class equipBag : MonoBehaviour
|
||||
}
|
||||
#endif
|
||||
|
||||
private bool MatchesCurrentFilter(equipmentSO equipment)
|
||||
{
|
||||
if (equipment == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
EquipFilterMode mode = GetSelectedFilterMode();
|
||||
bool hasSpecialSkill = equipment.sa_skillID > 0;
|
||||
bool hasIllusionSkill = equipment.ia_skillID > 0;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case EquipFilterMode.All:
|
||||
return true;
|
||||
case EquipFilterMode.HasSpecialSkill:
|
||||
return hasSpecialSkill;
|
||||
case EquipFilterMode.HasIllusionSkill:
|
||||
return hasIllusionSkill;
|
||||
case EquipFilterMode.HasAnySkill:
|
||||
return hasSpecialSkill || hasIllusionSkill;
|
||||
case EquipFilterMode.HasNoSkill:
|
||||
return !hasSpecialSkill && !hasIllusionSkill;
|
||||
case EquipFilterMode.HasDualSkill:
|
||||
return hasSpecialSkill && hasIllusionSkill;
|
||||
case EquipFilterMode.Type0:
|
||||
return equipment.skillType == equipmentSO.EquipmentSkillType.题海战术;
|
||||
case EquipFilterMode.Type1:
|
||||
return equipment.skillType == equipmentSO.EquipmentSkillType.诛锄异己;
|
||||
case EquipFilterMode.Type2:
|
||||
return equipment.skillType == equipmentSO.EquipmentSkillType.逸乐共谋;
|
||||
case EquipFilterMode.Type3:
|
||||
return equipment.skillType == equipmentSO.EquipmentSkillType.完美至上;
|
||||
case EquipFilterMode.Type4:
|
||||
return equipment.skillType == equipmentSO.EquipmentSkillType.涵养心境;
|
||||
case EquipFilterMode.Type5:
|
||||
return equipment.skillType == equipmentSO.EquipmentSkillType.众志成城;
|
||||
case EquipFilterMode.Type6:
|
||||
return equipment.skillType == equipmentSO.EquipmentSkillType.过激行为;
|
||||
case EquipFilterMode.Type7:
|
||||
return equipment.skillType == equipmentSO.EquipmentSkillType.二次形变;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void SortEquipments(List<equipmentSO> equipments)
|
||||
{
|
||||
if (equipments == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EquipOrderMode mode = GetSelectedOrderMode();
|
||||
equipments.Sort((left, right) => CompareEquipments(left, right, mode));
|
||||
}
|
||||
|
||||
private EquipFilterMode GetSelectedFilterMode()
|
||||
{
|
||||
int index = filterDropdown != null ? Mathf.Clamp(filterDropdown.value, 0, FilterOptions.Length - 1) : 0;
|
||||
return FilterOptions[index].mode;
|
||||
}
|
||||
|
||||
private EquipOrderMode GetSelectedOrderMode()
|
||||
{
|
||||
int index = orderDropdown != null ? Mathf.Clamp(orderDropdown.value, 0, OrderOptions.Length - 1) : 0;
|
||||
return OrderOptions[index].mode;
|
||||
}
|
||||
|
||||
private void HandleEquipmentClicked(equipmentSO equipment)
|
||||
{
|
||||
if (equipment == null)
|
||||
@@ -170,7 +422,7 @@ public class equipBag : MonoBehaviour
|
||||
spawnedItems.Clear();
|
||||
}
|
||||
|
||||
private static int CompareEquipments(equipmentSO left, equipmentSO right)
|
||||
private static int CompareEquipments(equipmentSO left, equipmentSO right, EquipOrderMode mode)
|
||||
{
|
||||
if (left == right)
|
||||
{
|
||||
@@ -187,14 +439,80 @@ public class equipBag : MonoBehaviour
|
||||
return -1;
|
||||
}
|
||||
|
||||
int levelCompare = right.level.CompareTo(left.level);
|
||||
if (levelCompare != 0)
|
||||
switch (mode)
|
||||
{
|
||||
return levelCompare;
|
||||
case EquipOrderMode.AcquireAsc:
|
||||
return CompareAcquire(left, right, false);
|
||||
case EquipOrderMode.AcquireDesc:
|
||||
return CompareAcquire(left, right, true);
|
||||
case EquipOrderMode.QualityAsc:
|
||||
return CompareQuality(left, right, false);
|
||||
case EquipOrderMode.QualityDesc:
|
||||
return CompareQuality(left, right, true);
|
||||
default:
|
||||
return CompareAcquire(left, right, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static int CompareAcquire(equipmentSO left, equipmentSO right, bool descending)
|
||||
{
|
||||
ParseEquipmentSortKey(left, out long leftDate, out long leftId);
|
||||
ParseEquipmentSortKey(right, out long rightDate, out long rightId);
|
||||
|
||||
int dateCompare = leftDate.CompareTo(rightDate);
|
||||
if (dateCompare != 0)
|
||||
{
|
||||
return descending ? -dateCompare : dateCompare;
|
||||
}
|
||||
|
||||
string leftName = left.GetCurrentTierDisplayName();
|
||||
string rightName = right.GetCurrentTierDisplayName();
|
||||
return string.Compare(leftName, rightName, StringComparison.Ordinal);
|
||||
int idCompare = leftId.CompareTo(rightId);
|
||||
if (idCompare != 0)
|
||||
{
|
||||
return descending ? -idCompare : idCompare;
|
||||
}
|
||||
|
||||
string leftName = left.GetDisplayTierName();
|
||||
string rightName = right.GetDisplayTierName();
|
||||
int nameCompare = string.Compare(leftName, rightName, StringComparison.Ordinal);
|
||||
return descending ? -nameCompare : nameCompare;
|
||||
}
|
||||
|
||||
private static int CompareQuality(equipmentSO left, equipmentSO right, bool descending)
|
||||
{
|
||||
int qualityCompare = left.GetVisualQualityColorIndex().CompareTo(right.GetVisualQualityColorIndex());
|
||||
if (qualityCompare != 0)
|
||||
{
|
||||
return descending ? -qualityCompare : qualityCompare;
|
||||
}
|
||||
|
||||
return CompareAcquire(left, right, true);
|
||||
}
|
||||
|
||||
private static void ParseEquipmentSortKey(equipmentSO equipment, out long datePart, out long idPart)
|
||||
{
|
||||
datePart = 0L;
|
||||
idPart = 0L;
|
||||
|
||||
if (equipment == null || string.IsNullOrWhiteSpace(equipment.name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string raw = equipment.name;
|
||||
if (raw.StartsWith("type", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
int firstUnderscore = raw.IndexOf('_');
|
||||
if (firstUnderscore >= 0 && firstUnderscore + 1 < raw.Length)
|
||||
{
|
||||
raw = raw.Substring(firstUnderscore + 1);
|
||||
}
|
||||
}
|
||||
|
||||
string[] parts = raw.Split('_');
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
long.TryParse(parts[0], out datePart);
|
||||
long.TryParse(parts[1], out idPart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user