Files
bansonic_beta_main/Assets/playerBagSystem/uBag.cs
T

1274 lines
39 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using TMPro;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class uBag : MonoBehaviour
{
private enum BagCategory
{
All,
Cultivation,
Precious,
Other
}
private enum PreciousKind
{
NotebookClue,
Character,
Level
}
private sealed class BagEntry
{
public string stableId;
public string displayName;
public string countText;
public string amountText;
public string usage;
public string description;
public Sprite icon;
public BagCategory category;
public int sortPriority;
public ItemRarity rarity;
}
[Header("category toggles")]
public ToggleGroup bagToggleGroup;
public Toggle allToggle;
public Toggle cultivateToggle;
public Toggle preciousToggle;
public Toggle otherToggle;
public Toggle equipSystemToggle;
[Header("OBJ")]
public GameObject bagObj;
public GameObject equipObj;
public Button closeBagButton;
[Header("right panel")]
public Image btmImg;
public Image itemDprofile;
public TextMeshProUGUI itemAmount;
public Text itemName;
public Text itemUse;
public Text itemDescription;
[Header("list")]
public Transform itemParent;
public GameObject itemPrefab;
public Text emptyText;
[Min(1)] public int spawnBatchSize = 16;
[Header("introduction")]
public GameObject itemIntroductionPrefab;
public float introductionHoverDelay = 0.5f;
public int introductionHorizontalOffset = 12;
[Header("colors")]
public Color fallbackColor = Color.white;
public Sprite fallbackItemIcon;
public ItemRarityColorConfigSO rarityColorConfig;
[Header("paths")]
[SerializeField] private string notebookEditorPath = "Assets/Resources/so/notebook";
[SerializeField] private string notebookRuntimePath = "so/notebook";
[SerializeField] private string storeItemEditorPath = "Assets/Resources/so/storeSO";
[SerializeField] private string storeItemRuntimePath = "so/storeSO";
[SerializeField] private string expBottleEditorPath = "Assets/storeSystem/items/medicines";
[SerializeField] private string growthMaterialEditorPath = "Assets/storeSystem/items/medicines";
[SerializeField] private string equipmentConsumableEditorPath = "Assets/storeSystem/items/medicines";
private readonly List<GameObject> spawnedItems = new List<GameObject>();
private readonly List<BagEntry> allEntries = new List<BagEntry>();
private readonly Dictionary<uBagItemPrefab, BagEntry> viewEntries = new Dictionary<uBagItemPrefab, BagEntry>();
private Coroutine rebuildRoutine;
private BagCategory currentCategory = BagCategory.All;
private GameObject spawnedIntroduction;
private uBagItemPrefab activePreviewSource;
private void Awake()
{
InitializeToggleGroup();
BindToggles();
BindCloseButton();
BindLedgerEvents();
InitializeViewMode();
SelectDefaultCategory();
}
private void OnEnable()
{
InitializeToggleGroup();
BindToggles();
BindCloseButton();
BindLedgerEvents();
InitializeViewMode();
Rebuild();
}
private void OnDisable()
{
UnbindToggle(allToggle, HandleAllChanged);
UnbindToggle(cultivateToggle, HandleCultivateChanged);
UnbindToggle(preciousToggle, HandlePreciousChanged);
UnbindToggle(otherToggle, HandleOtherChanged);
UnbindToggle(equipSystemToggle, HandleEquipSystemChanged);
UnbindCloseButton();
UnbindLedgerEvents();
HideCurrentPreview();
}
private void OnDestroy()
{
btmandtopController.RefreshOverlayVisibilityState();
}
private void InitializeToggleGroup()
{
if (bagToggleGroup == null)
{
return;
}
bagToggleGroup.allowSwitchOff = false;
AssignToggleGroup(allToggle);
AssignToggleGroup(cultivateToggle);
AssignToggleGroup(preciousToggle);
AssignToggleGroup(otherToggle);
}
private void AssignToggleGroup(Toggle toggle)
{
if (toggle == null || bagToggleGroup == null)
{
return;
}
toggle.group = bagToggleGroup;
}
private void BindToggles()
{
RebindToggle(allToggle, HandleAllChanged);
RebindToggle(cultivateToggle, HandleCultivateChanged);
RebindToggle(preciousToggle, HandlePreciousChanged);
RebindToggle(otherToggle, HandleOtherChanged);
RebindToggle(equipSystemToggle, HandleEquipSystemChanged);
}
private void BindCloseButton()
{
if (closeBagButton == null)
{
return;
}
closeBagButton.onClick.RemoveListener(HandleCloseBagClicked);
closeBagButton.onClick.AddListener(HandleCloseBagClicked);
}
private void UnbindCloseButton()
{
if (closeBagButton == null)
{
return;
}
closeBagButton.onClick.RemoveListener(HandleCloseBagClicked);
}
private void RebindToggle(Toggle toggle, UnityAction<bool> action)
{
if (toggle == null)
{
return;
}
toggle.onValueChanged.RemoveListener(action);
toggle.onValueChanged.AddListener(action);
}
private void UnbindToggle(Toggle toggle, UnityAction<bool> action)
{
if (toggle == null)
{
return;
}
toggle.onValueChanged.RemoveListener(action);
}
private void BindLedgerEvents()
{
ExpBottleLedger.EnsureInstance().OnBottleCountChanged -= HandleInventoryChanged;
ExpBottleLedger.EnsureInstance().OnBottleCountChanged += HandleInventoryChanged;
ExpBottleLedger.EnsureInstance().OnLedgerReloaded -= HandleInventoryReloaded;
ExpBottleLedger.EnsureInstance().OnLedgerReloaded += HandleInventoryReloaded;
DushMaterialLedger.EnsureInstance().OnMaterialCountChanged -= HandleGrowthMaterialChanged;
DushMaterialLedger.EnsureInstance().OnMaterialCountChanged += HandleGrowthMaterialChanged;
EquipmentConsumableLedger.EnsureInstance().OnCountChanged -= HandleEquipmentConsumableChanged;
EquipmentConsumableLedger.EnsureInstance().OnCountChanged += HandleEquipmentConsumableChanged;
}
private void UnbindLedgerEvents()
{
ExpBottleLedger.EnsureInstance().OnBottleCountChanged -= HandleInventoryChanged;
ExpBottleLedger.EnsureInstance().OnLedgerReloaded -= HandleInventoryReloaded;
DushMaterialLedger.EnsureInstance().OnMaterialCountChanged -= HandleGrowthMaterialChanged;
EquipmentConsumableLedger.EnsureInstance().OnCountChanged -= HandleEquipmentConsumableChanged;
}
private void SelectDefaultCategory()
{
if (allToggle != null)
{
allToggle.isOn = true;
ApplyCategory(BagCategory.All);
return;
}
ApplyCategory(BagCategory.All);
}
private void HandleAllChanged(bool isOn)
{
if (isOn)
{
ApplyCategory(BagCategory.All);
}
}
private void HandleCultivateChanged(bool isOn)
{
if (isOn)
{
ApplyCategory(BagCategory.Cultivation);
}
}
private void HandlePreciousChanged(bool isOn)
{
if (isOn)
{
ApplyCategory(BagCategory.Precious);
}
}
private void HandleOtherChanged(bool isOn)
{
if (isOn)
{
ApplyCategory(BagCategory.Other);
}
}
private void HandleEquipSystemChanged(bool isOn)
{
SetObjectActive(bagObj, !isOn);
SetObjectActive(equipObj, isOn);
}
private void HandleCloseBagClicked()
{
Destroy(gameObject);
}
private void ApplyCategory(BagCategory category)
{
currentCategory = category;
SetToggleInteractable(allToggle, category != BagCategory.All);
SetToggleInteractable(cultivateToggle, category != BagCategory.Cultivation);
SetToggleInteractable(preciousToggle, category != BagCategory.Precious);
SetToggleInteractable(otherToggle, category != BagCategory.Other);
Rebuild();
}
private void SetToggleInteractable(Toggle toggle, bool interactable)
{
if (toggle != null)
{
toggle.interactable = interactable;
}
}
private void SetObjectActive(GameObject target, bool active)
{
if (target != null)
{
target.SetActive(active);
}
}
private void InitializeViewMode()
{
if (equipSystemToggle != null)
{
equipSystemToggle.onValueChanged.RemoveListener(HandleEquipSystemChanged);
equipSystemToggle.onValueChanged.AddListener(HandleEquipSystemChanged);
HandleEquipSystemChanged(equipSystemToggle.isOn);
return;
}
SetObjectActive(bagObj, true);
SetObjectActive(equipObj, false);
}
private void HandleInventoryChanged(ExpBottleKind _, int __)
{
Rebuild();
}
private void HandleInventoryReloaded()
{
Rebuild();
}
private void HandleGrowthMaterialChanged(DushMaterialKind _, int __)
{
Rebuild();
}
private void HandleEquipmentConsumableChanged(EquipmentConsumableKind _, int __)
{
Rebuild();
}
public void Rebuild()
{
BuildEntries();
if (rebuildRoutine != null)
{
StopCoroutine(rebuildRoutine);
rebuildRoutine = null;
}
ClearSpawnedItems();
if (!isActiveAndEnabled)
{
return;
}
ClearRightPanel();
rebuildRoutine = StartCoroutine(RebuildAsync());
}
public void SelectItemForDetail(uBagItemPrefab source)
{
if (source == null)
{
return;
}
if (!viewEntries.TryGetValue(source, out BagEntry entry) || entry == null)
{
ClearRightPanel();
return;
}
ApplyRightPanel(entry);
}
public void ShowPreviewFor(uBagItemPrefab source)
{
if (source == null || itemIntroductionPrefab == null)
{
return;
}
if (!viewEntries.TryGetValue(source, out BagEntry entry) || entry == null)
{
return;
}
HideCurrentPreview();
Transform previewParent = ResolveIntroductionParent(source);
if (previewParent == null)
{
return;
}
spawnedIntroduction = Instantiate(itemIntroductionPrefab, previewParent);
spawnedIntroduction.name = $"uBagPreview_{entry.stableId}";
spawnedIntroduction.SetActive(true);
spawnedIntroduction.transform.SetAsLastSibling();
activePreviewSource = source;
var previewView = spawnedIntroduction.GetComponent<bagItemPreviewPrefab>();
if (previewView != null)
{
Sprite icon = entry.icon != null ? entry.icon : fallbackItemIcon;
Color color = rarityColorConfig != null
? rarityColorConfig.GetColor(entry.rarity, fallbackColor)
: fallbackColor;
previewView.Bind(color, icon, entry.displayName, entry.usage, entry.description, entry.amountText);
}
PositionIntroduction(source, spawnedIntroduction);
}
public void HidePreviewFor(uBagItemPrefab source)
{
if (source != null && source != activePreviewSource)
{
return;
}
HideCurrentPreview();
}
private void BuildEntries()
{
allEntries.Clear();
List<storeItemSO> storeItems = new List<storeItemSO>(LoadStoreItems());
AddExpBottleEntries(storeItems);
AddGrowthMaterialEntries(storeItems);
AddEquipmentConsumableEntries(storeItems);
AddNotebookPreciousEntries();
AddOwnedStorePreciousEntries(storeItems);
allEntries.Sort(CompareEntries);
}
private void AddExpBottleEntries(List<storeItemSO> storeItems)
{
var ledger = ExpBottleLedger.EnsureInstance();
var definitions = LoadExpBottleDefinitions();
foreach (var descriptor in ExpBottleCatalog.All)
{
int count = ledger.GetCount(descriptor.Kind);
if (count <= 0)
{
continue;
}
expBottlesSO definition = FindExpBottleDefinition(definitions, descriptor.Kind);
storeItemSO storeItem = FindStoreItemForExpBottle(storeItems, descriptor.Kind);
expBottlesSO sourceDefinition = storeItem != null && storeItem.associatedExpBottle != null
? storeItem.associatedExpBottle
: definition;
allEntries.Add(new BagEntry
{
stableId = descriptor.Key,
displayName = storeItem != null && !string.IsNullOrEmpty(storeItem.itemName)
? storeItem.itemName
: definition != null && !string.IsNullOrEmpty(definition.expBottleName) ? definition.expBottleName : descriptor.DisplayName,
countText = count.ToString(),
amountText = count.ToString(),
usage = ResolveExpBottleUsage(sourceDefinition),
description = BuildPreferredDescription(
storeItem != null ? storeItem.itemDetailedDescription : null,
sourceDefinition != null ? sourceDefinition.expBottleDescription : null,
storeItem != null ? storeItem.itemDescription : null),
icon = ResolvePreferredSprite(
storeItem != null ? storeItem.itemIcon : null,
sourceDefinition != null ? sourceDefinition.expBottleSprite : null,
fallbackItemIcon),
category = BagCategory.Cultivation,
sortPriority = 10,
rarity = storeItem != null ? storeItem.itemRarity : sourceDefinition != null ? sourceDefinition.itemRarity : ItemRarity.Common
});
}
}
private void AddGrowthMaterialEntries(List<storeItemSO> storeItems)
{
var ledger = DushMaterialLedger.EnsureInstance();
var definitions = LoadGrowthMaterialDefinitions();
foreach (var descriptor in DushMaterialCatalog.All)
{
int count = ledger.GetCount(descriptor.Kind);
if (count <= 0)
{
continue;
}
growthMaterialSO definition = FindGrowthMaterialDefinition(definitions, descriptor.Kind);
storeItemSO storeItem = FindStoreItemForGrowthMaterial(storeItems, descriptor.Kind);
growthMaterialSO sourceDefinition = storeItem != null && storeItem.associatedGrowthMaterial != null
? storeItem.associatedGrowthMaterial
: definition;
allEntries.Add(new BagEntry
{
stableId = descriptor.Key,
displayName = storeItem != null && !string.IsNullOrEmpty(storeItem.itemName)
? storeItem.itemName
: definition != null && !string.IsNullOrEmpty(definition.growthMaterialName) ? definition.growthMaterialName : descriptor.DisplayName,
countText = count.ToString(),
amountText = count.ToString(),
usage = ResolveGrowthMaterialUsage(sourceDefinition),
description = BuildPreferredDescription(
storeItem != null ? storeItem.itemDetailedDescription : null,
sourceDefinition != null ? sourceDefinition.growthMaterialDescription : null,
storeItem != null ? storeItem.itemDescription : null),
icon = ResolvePreferredSprite(
storeItem != null ? storeItem.itemIcon : null,
sourceDefinition != null ? sourceDefinition.growthMaterialSprite : null,
fallbackItemIcon),
category = BagCategory.Cultivation,
sortPriority = 20,
rarity = storeItem != null ? storeItem.itemRarity : sourceDefinition != null ? sourceDefinition.itemRarity : ItemRarity.Uncommon
});
}
}
private void AddEquipmentConsumableEntries(List<storeItemSO> storeItems)
{
var ledger = EquipmentConsumableLedger.EnsureInstance();
var definitions = LoadEquipmentConsumableDefinitions();
foreach (var descriptor in EquipmentConsumableCatalog.All)
{
int count = ledger.GetCount(descriptor.Kind);
if (count <= 0)
{
continue;
}
equipmentConsumableSO definition = FindEquipmentConsumableDefinition(definitions, descriptor.Kind);
storeItemSO storeItem = FindStoreItemForEquipmentConsumable(storeItems, descriptor.Kind);
equipmentConsumableSO sourceDefinition = storeItem != null && storeItem.associatedEquipmentConsumable != null
? storeItem.associatedEquipmentConsumable
: definition;
allEntries.Add(new BagEntry
{
stableId = descriptor.Key,
displayName = storeItem != null && !string.IsNullOrEmpty(storeItem.itemName)
? storeItem.itemName
: definition != null && !string.IsNullOrEmpty(definition.consumableName) ? definition.consumableName : descriptor.DisplayName,
countText = count.ToString(),
amountText = count.ToString(),
usage = ResolveEquipmentConsumableUsage(sourceDefinition),
description = BuildPreferredDescription(
storeItem != null ? storeItem.itemDetailedDescription : null,
sourceDefinition != null ? sourceDefinition.consumableDescription : null,
storeItem != null ? storeItem.itemDescription : null),
icon = ResolvePreferredSprite(
storeItem != null ? storeItem.itemIcon : null,
sourceDefinition != null ? sourceDefinition.consumableSprite : null,
fallbackItemIcon),
category = BagCategory.Cultivation,
sortPriority = 30,
rarity = storeItem != null ? storeItem.itemRarity : sourceDefinition != null ? sourceDefinition.itemRarity : ItemRarity.Uncommon
});
}
}
private void AddNotebookPreciousEntries()
{
var seenIds = new HashSet<string>();
foreach (var story in LoadNotebookDefinitions())
{
if (story == null || !story.isUnlocked)
{
continue;
}
string stableId = $"notebook_{story.class_id}";
if (!seenIds.Add(stableId))
{
continue;
}
allEntries.Add(new BagEntry
{
stableId = stableId,
displayName = story.class_name,
countText = "1",
amountText = "1",
usage = ResolveNotebookUsage(story),
description = story.class_description,
icon = ResolvePreferredSprite(story.class_image, fallbackItemIcon),
category = BagCategory.Precious,
sortPriority = 100,
rarity = story.itemRarity
});
}
}
private void AddOwnedStorePreciousEntries(List<storeItemSO> storeItems)
{
var ownership = StoreOwnershipLedger.EnsureInstance();
foreach (var item in storeItems)
{
if (item == null || !ownership.IsOwned(item))
{
continue;
}
if (item.itemType != storeItemSO.ItemType.character && item.itemType != storeItemSO.ItemType.song)
{
continue;
}
PreciousKind kind = item.itemType == storeItemSO.ItemType.character ? PreciousKind.Character : PreciousKind.Level;
allEntries.Add(new BagEntry
{
stableId = $"store_{item.itemID}",
displayName = item.itemName,
countText = "1",
amountText = "1",
usage = kind == PreciousKind.Character ? "角色" : "关卡",
description = BuildPreferredDescription(item.itemDetailedDescription, item.itemDescription),
icon = ResolvePreferredSprite(item.itemIcon, fallbackItemIcon),
category = BagCategory.Precious,
sortPriority = kind == PreciousKind.Character ? 110 : 120,
rarity = item.itemRarity
});
}
}
private IEnumerator RebuildAsync()
{
List<BagEntry> visibleEntries = FilterEntries();
UpdateEmptyState(visibleEntries.Count == 0);
uBagItemPrefab firstView = null;
int spawnedInBatch = 0;
for (int i = 0; i < visibleEntries.Count; i++)
{
uBagItemPrefab spawnedView = SpawnEntry(visibleEntries[i]);
if (firstView == null && spawnedView != null)
{
firstView = spawnedView;
}
spawnedInBatch++;
if (spawnedInBatch >= spawnBatchSize)
{
spawnedInBatch = 0;
yield return null;
}
}
if (firstView != null)
{
SelectItemForDetail(firstView);
}
else
{
ClearRightPanel();
}
rebuildRoutine = null;
}
private List<BagEntry> FilterEntries()
{
var result = new List<BagEntry>();
for (int i = 0; i < allEntries.Count; i++)
{
BagEntry entry = allEntries[i];
if (entry == null)
{
continue;
}
if (currentCategory != BagCategory.All && entry.category != currentCategory)
{
continue;
}
result.Add(entry);
}
return result;
}
private uBagItemPrefab SpawnEntry(BagEntry entry)
{
if (entry == null || itemPrefab == null || itemParent == null)
{
return null;
}
GameObject instance = Instantiate(itemPrefab, itemParent);
instance.name = $"uBagItem_{entry.stableId}";
spawnedItems.Add(instance);
uBagItemPrefab prefabView = instance.GetComponent<uBagItemPrefab>();
if (prefabView != null)
{
Sprite icon = entry.icon != null ? entry.icon : fallbackItemIcon;
Color color = rarityColorConfig != null
? rarityColorConfig.GetColor(entry.rarity, fallbackColor)
: fallbackColor;
prefabView.Bind(this, icon, entry.countText, color, introductionHoverDelay);
viewEntries[prefabView] = entry;
}
return prefabView;
}
private void ClearSpawnedItems()
{
HideCurrentPreview();
viewEntries.Clear();
for (int i = itemParent != null ? itemParent.childCount - 1 : -1; i >= 0; i--)
{
Transform child = itemParent.GetChild(i);
if (child != null)
{
Destroy(child.gameObject);
}
}
spawnedItems.Clear();
UpdateEmptyState(false);
}
private void UpdateEmptyState(bool visible)
{
if (emptyText != null)
{
emptyText.gameObject.SetActive(visible);
if (visible)
{
emptyText.text = "暂无物品";
}
}
}
private void ApplyRightPanel(BagEntry entry)
{
if (entry == null)
{
ClearRightPanel();
return;
}
Sprite icon = entry.icon != null ? entry.icon : fallbackItemIcon;
Color color = rarityColorConfig != null
? rarityColorConfig.GetColor(entry.rarity, fallbackColor)
: fallbackColor;
if (btmImg != null)
{
btmImg.color = color;
}
if (itemDprofile != null)
{
itemDprofile.sprite = icon;
itemDprofile.enabled = icon != null;
itemDprofile.color = Color.white;
}
if (itemAmount != null)
{
itemAmount.text = entry.amountText ?? string.Empty;
}
if (itemName != null)
{
itemName.text = entry.displayName ?? string.Empty;
}
if (itemUse != null)
{
itemUse.text = entry.usage ?? string.Empty;
}
if (itemDescription != null)
{
itemDescription.text = entry.description ?? string.Empty;
}
}
private void ClearRightPanel()
{
if (btmImg != null)
{
btmImg.color = fallbackColor;
}
if (itemDprofile != null)
{
itemDprofile.sprite = fallbackItemIcon;
itemDprofile.enabled = fallbackItemIcon != null;
itemDprofile.color = Color.white;
}
if (itemAmount != null)
{
itemAmount.text = string.Empty;
}
if (itemName != null)
{
itemName.text = string.Empty;
}
if (itemUse != null)
{
itemUse.text = string.Empty;
}
if (itemDescription != null)
{
itemDescription.text = string.Empty;
}
}
private static int CompareEntries(BagEntry left, BagEntry right)
{
if (ReferenceEquals(left, right))
{
return 0;
}
if (left == null)
{
return 1;
}
if (right == null)
{
return -1;
}
int categoryResult = left.category.CompareTo(right.category);
if (categoryResult != 0)
{
return categoryResult;
}
int priorityResult = left.sortPriority.CompareTo(right.sortPriority);
if (priorityResult != 0)
{
return priorityResult;
}
return string.CompareOrdinal(left.displayName, right.displayName);
}
private expBottlesSO[] LoadExpBottleDefinitions()
{
var result = new List<expBottlesSO>();
#if UNITY_EDITOR
if (!Application.isPlaying && !string.IsNullOrEmpty(expBottleEditorPath))
{
string[] guids = AssetDatabase.FindAssets("t:expBottlesSO", new[] { expBottleEditorPath });
for (int i = 0; i < guids.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
expBottlesSO asset = AssetDatabase.LoadAssetAtPath<expBottlesSO>(path);
if (asset != null)
{
result.Add(asset);
}
}
}
#endif
result.AddRange(Resources.LoadAll<expBottlesSO>(string.Empty));
return result.ToArray();
}
private growthMaterialSO[] LoadGrowthMaterialDefinitions()
{
var result = new List<growthMaterialSO>();
#if UNITY_EDITOR
if (!Application.isPlaying && !string.IsNullOrEmpty(growthMaterialEditorPath))
{
string[] guids = AssetDatabase.FindAssets("t:growthMaterialSO", new[] { growthMaterialEditorPath });
for (int i = 0; i < guids.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
growthMaterialSO asset = AssetDatabase.LoadAssetAtPath<growthMaterialSO>(path);
if (asset != null)
{
result.Add(asset);
}
}
}
#endif
result.AddRange(Resources.LoadAll<growthMaterialSO>(string.Empty));
return result.ToArray();
}
private equipmentConsumableSO[] LoadEquipmentConsumableDefinitions()
{
var result = new List<equipmentConsumableSO>();
#if UNITY_EDITOR
if (!Application.isPlaying && !string.IsNullOrEmpty(equipmentConsumableEditorPath))
{
string[] guids = AssetDatabase.FindAssets("t:equipmentConsumableSO", new[] { equipmentConsumableEditorPath });
for (int i = 0; i < guids.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
equipmentConsumableSO asset = AssetDatabase.LoadAssetAtPath<equipmentConsumableSO>(path);
if (asset != null)
{
result.Add(asset);
}
}
}
#endif
result.AddRange(Resources.LoadAll<equipmentConsumableSO>(string.Empty));
return result.ToArray();
}
private IEnumerable<notebook_faterType> LoadNotebookDefinitions()
{
var result = new List<notebook_faterType>();
var seen = new HashSet<int>();
#if UNITY_EDITOR
if (!Application.isPlaying && !string.IsNullOrEmpty(notebookEditorPath))
{
string[] guids = AssetDatabase.FindAssets("t:notebook_faterType", new[] { notebookEditorPath });
for (int i = 0; i < guids.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
notebook_faterType asset = AssetDatabase.LoadAssetAtPath<notebook_faterType>(path);
if (asset != null && seen.Add(asset.class_id))
{
result.Add(asset);
}
}
}
#endif
if (!string.IsNullOrEmpty(notebookRuntimePath))
{
notebook_faterType[] resources = Resources.LoadAll<notebook_faterType>(notebookRuntimePath);
for (int i = 0; i < resources.Length; i++)
{
notebook_faterType asset = resources[i];
if (asset != null && seen.Add(asset.class_id))
{
result.Add(asset);
}
}
}
return result;
}
private IEnumerable<storeItemSO> LoadStoreItems()
{
var result = new List<storeItemSO>();
var seen = new HashSet<int>();
#if UNITY_EDITOR
if (!Application.isPlaying && !string.IsNullOrEmpty(storeItemEditorPath))
{
string[] guids = AssetDatabase.FindAssets("t:storeItemSO", new[] { storeItemEditorPath });
for (int i = 0; i < guids.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
storeItemSO asset = AssetDatabase.LoadAssetAtPath<storeItemSO>(path);
if (asset != null && seen.Add(asset.itemID))
{
result.Add(asset);
}
}
}
#endif
if (!string.IsNullOrEmpty(storeItemRuntimePath))
{
storeItemSO[] resources = Resources.LoadAll<storeItemSO>(storeItemRuntimePath);
for (int i = 0; i < resources.Length; i++)
{
storeItemSO asset = resources[i];
if (asset != null && seen.Add(asset.itemID))
{
result.Add(asset);
}
}
}
return result;
}
private static expBottlesSO FindExpBottleDefinition(expBottlesSO[] definitions, ExpBottleKind kind)
{
if (definitions == null)
{
return null;
}
for (int i = 0; i < definitions.Length; i++)
{
if (definitions[i] != null && definitions[i].bottleKind == kind)
{
return definitions[i];
}
}
return null;
}
private static growthMaterialSO FindGrowthMaterialDefinition(growthMaterialSO[] definitions, DushMaterialKind kind)
{
if (definitions == null)
{
return null;
}
for (int i = 0; i < definitions.Length; i++)
{
if (definitions[i] != null && definitions[i].materialKind == kind)
{
return definitions[i];
}
}
return null;
}
private static equipmentConsumableSO FindEquipmentConsumableDefinition(equipmentConsumableSO[] definitions, EquipmentConsumableKind kind)
{
if (definitions == null)
{
return null;
}
for (int i = 0; i < definitions.Length; i++)
{
if (definitions[i] != null && definitions[i].consumableKind == kind)
{
return definitions[i];
}
}
return null;
}
private static storeItemSO FindStoreItemForExpBottle(List<storeItemSO> storeItems, ExpBottleKind kind)
{
if (storeItems == null)
{
return null;
}
for (int i = 0; i < storeItems.Count; i++)
{
storeItemSO item = storeItems[i];
if (item != null
&& item.itemType == storeItemSO.ItemType.consumable
&& item.associatedExpBottle != null
&& item.associatedExpBottle.bottleKind == kind)
{
return item;
}
}
return null;
}
private static storeItemSO FindStoreItemForGrowthMaterial(List<storeItemSO> storeItems, DushMaterialKind kind)
{
if (storeItems == null)
{
return null;
}
for (int i = 0; i < storeItems.Count; i++)
{
storeItemSO item = storeItems[i];
if (item != null
&& item.itemType == storeItemSO.ItemType.consumable
&& item.associatedGrowthMaterial != null
&& item.associatedGrowthMaterial.materialKind == kind)
{
return item;
}
}
return null;
}
private static storeItemSO FindStoreItemForEquipmentConsumable(List<storeItemSO> storeItems, EquipmentConsumableKind kind)
{
if (storeItems == null)
{
return null;
}
for (int i = 0; i < storeItems.Count; i++)
{
storeItemSO item = storeItems[i];
if (item != null
&& item.itemType == storeItemSO.ItemType.consumable
&& item.associatedEquipmentConsumable != null
&& item.associatedEquipmentConsumable.consumableKind == kind)
{
return item;
}
}
return null;
}
private static string ResolveNotebookUsage(notebook_faterType story)
{
if (story == null)
{
return string.Empty;
}
switch (story.fatherType)
{
case notebook_faterType.notebook_fatherType.idols:
return "角色线索";
case notebook_faterType.notebook_fatherType.content:
return "故事线索";
default:
return "珍贵物品";
}
}
private static string ResolveExpBottleUsage(expBottlesSO definition)
{
if (definition != null && !string.IsNullOrWhiteSpace(definition.expBottleUsage))
{
return definition.expBottleUsage;
}
return "角色培养";
}
private static string ResolveGrowthMaterialUsage(growthMaterialSO definition)
{
if (definition != null && !string.IsNullOrWhiteSpace(definition.growthMaterialUsage))
{
return definition.growthMaterialUsage;
}
return "角色突破";
}
private static string ResolveEquipmentConsumableUsage(equipmentConsumableSO definition)
{
if (definition != null && !string.IsNullOrWhiteSpace(definition.consumableUsage))
{
return definition.consumableUsage;
}
if (definition == null)
{
return "装备材料";
}
switch (definition.consumableType)
{
case equipmentConsumableSO.EquipmentConsumableType.UpgradeMaterial:
return "装备升级";
case equipmentConsumableSO.EquipmentConsumableType.BreakthroughMaterial:
return "装备幻化";
case equipmentConsumableSO.EquipmentConsumableType.TransferMaterial:
return "装备洗炼";
case equipmentConsumableSO.EquipmentConsumableType.FinalDreamMaterial:
return "梦醒登顶";
default:
return "装备材料";
}
}
private static Sprite ResolvePreferredSprite(params Sprite[] sprites)
{
for (int i = 0; i < sprites.Length; i++)
{
if (sprites[i] != null)
{
return sprites[i];
}
}
return null;
}
private static string BuildPreferredDescription(params string[] candidates)
{
for (int i = 0; i < candidates.Length; i++)
{
if (!string.IsNullOrWhiteSpace(candidates[i]))
{
return candidates[i];
}
}
return string.Empty;
}
private Transform ResolveIntroductionParent(uBagItemPrefab source)
{
if (source == null)
{
return itemParent;
}
Canvas canvas = source.GetComponentInParent<Canvas>();
if (canvas != null)
{
return canvas.transform;
}
return itemParent;
}
private void PositionIntroduction(uBagItemPrefab source, GameObject introduction)
{
if (source == null || introduction == null)
{
return;
}
RectTransform sourceRect = source.transform as RectTransform;
RectTransform introductionRect = introduction.transform as RectTransform;
Canvas canvas = introduction.GetComponentInParent<Canvas>();
RectTransform canvasRect = canvas != null ? canvas.transform as RectTransform : null;
if (sourceRect == null || introductionRect == null || canvasRect == null)
{
return;
}
Canvas.ForceUpdateCanvases();
LayoutRebuilder.ForceRebuildLayoutImmediate(introductionRect);
Vector3[] corners = new Vector3[4];
sourceRect.GetWorldCorners(corners);
Vector3 sourceRightCenter = (corners[2] + corners[3]) * 0.5f;
Camera uiCamera = canvas != null ? canvas.worldCamera : null;
Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(uiCamera, sourceRightCenter);
RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvasRect,
screenPoint,
uiCamera,
out Vector2 localPoint);
introductionRect.anchorMin = new Vector2(0.5f, 0.5f);
introductionRect.anchorMax = new Vector2(0.5f, 0.5f);
introductionRect.pivot = new Vector2(0f, 0.5f);
introductionRect.anchoredPosition = localPoint + new Vector2(introductionHorizontalOffset, 0f);
introductionRect.localScale = Vector3.one;
introductionRect.localRotation = Quaternion.identity;
}
private void HideCurrentPreview()
{
activePreviewSource = null;
if (spawnedIntroduction != null)
{
Destroy(spawnedIntroduction);
spawnedIntroduction = null;
}
}
}