UI HUGE UPDATE
This commit is contained in:
@@ -0,0 +1,348 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Spine.Unity;
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
public sealed class HeroSkinResolvedData
|
||||
{
|
||||
public string skinId;
|
||||
public int heroId;
|
||||
public string skinName;
|
||||
public string ally_heroDesignation;
|
||||
public bool isBaseSkin;
|
||||
public bool isDefaultSkin;
|
||||
public bool unlockedByDefault;
|
||||
public string sourceDlcId;
|
||||
public int sortOrder;
|
||||
|
||||
public Sprite ally_heroImage;
|
||||
public Sprite ally_heroProfile;
|
||||
public Sprite ally_heroSelectIcon;
|
||||
public Sprite ally_heroIcon;
|
||||
public Sprite ally_heroPoster;
|
||||
public Sprite ally_hero_HD_image;
|
||||
public Sprite ally_hero_squareProfile;
|
||||
public SkeletonDataAsset ally_heroSpineData;
|
||||
public Color ally_heroThemeColor;
|
||||
public string skinDescription;
|
||||
|
||||
public AllyHero_SO ownerHero;
|
||||
public HeroSkinSO sourceSkin;
|
||||
}
|
||||
|
||||
public static class HeroSkinResolver
|
||||
{
|
||||
private const string RuntimeResourcesFolder = "so/heroSkins";
|
||||
private const string EditorSearchFolder = "Assets/Resources/so/heroSkins";
|
||||
|
||||
private static HeroSkinSO[] cachedAllSkins;
|
||||
private static readonly Dictionary<int, List<HeroSkinSO>> CachedByHeroId = new Dictionary<int, List<HeroSkinSO>>();
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
||||
private static void ResetStaticState()
|
||||
{
|
||||
cachedAllSkins = null;
|
||||
CachedByHeroId.Clear();
|
||||
}
|
||||
|
||||
public static void InvalidateCache()
|
||||
{
|
||||
cachedAllSkins = null;
|
||||
CachedByHeroId.Clear();
|
||||
}
|
||||
|
||||
public static List<HeroSkinResolvedData> GetSkinSet(AllyHero_SO hero, bool includeBaseSkin = true)
|
||||
{
|
||||
List<HeroSkinResolvedData> result = new List<HeroSkinResolvedData>();
|
||||
if (hero == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (includeBaseSkin)
|
||||
{
|
||||
result.Add(BuildBaseSkin(hero));
|
||||
}
|
||||
|
||||
List<HeroSkinSO> extras = GetExtraSkinsForHero(hero.ally_heroID);
|
||||
for (int i = 0; i < extras.Count; i++)
|
||||
{
|
||||
HeroSkinSO extraSkin = extras[i];
|
||||
if (extraSkin == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Add(BuildExtraSkin(hero, extraSkin));
|
||||
}
|
||||
|
||||
result.Sort(CompareResolvedSkin);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static HeroSkinResolvedData GetSkinById(AllyHero_SO hero, string skinId, bool fallbackToBase = true)
|
||||
{
|
||||
if (hero == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<HeroSkinResolvedData> skinSet = GetSkinSet(hero, true);
|
||||
string safeSkinId = string.IsNullOrWhiteSpace(skinId) ? string.Empty : skinId.Trim();
|
||||
for (int i = 0; i < skinSet.Count; i++)
|
||||
{
|
||||
HeroSkinResolvedData skin = skinSet[i];
|
||||
if (skin == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(skin.skinId, safeSkinId, StringComparison.Ordinal))
|
||||
{
|
||||
return skin;
|
||||
}
|
||||
}
|
||||
|
||||
return fallbackToBase ? BuildBaseSkin(hero) : null;
|
||||
}
|
||||
|
||||
public static HeroSkinResolvedData GetAccessibleSkinById(AllyHero_SO hero, string skinId, bool fallbackToBase = true)
|
||||
{
|
||||
HeroSkinResolvedData resolved = GetSkinById(hero, skinId, fallbackToBase);
|
||||
if (DlcContentAccess.IsSkinAccessible(resolved))
|
||||
{
|
||||
return resolved;
|
||||
}
|
||||
|
||||
return fallbackToBase ? BuildBaseSkin(hero) : null;
|
||||
}
|
||||
|
||||
public static HeroSkinResolvedData BuildBaseSkin(AllyHero_SO hero)
|
||||
{
|
||||
if (hero == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new HeroSkinResolvedData
|
||||
{
|
||||
skinId = BuildBaseSkinId(hero.ally_heroID),
|
||||
heroId = hero.ally_heroID,
|
||||
skinName = hero.ally_heroName,
|
||||
ally_heroDesignation = hero.ally_heroDesignation,
|
||||
isBaseSkin = true,
|
||||
isDefaultSkin = true,
|
||||
unlockedByDefault = true,
|
||||
sourceDlcId = string.Empty,
|
||||
sortOrder = int.MinValue,
|
||||
ally_heroImage = hero.ally_heroImage,
|
||||
ally_heroProfile = hero.ally_heroProfile,
|
||||
ally_heroSelectIcon = hero.ally_heroSelectIcon,
|
||||
ally_heroIcon = hero.ally_heroIcon,
|
||||
ally_heroPoster = hero.ally_heroPoster,
|
||||
ally_hero_HD_image = hero.ally_hero_HD_image,
|
||||
ally_hero_squareProfile = hero.ally_hero_squareProfile,
|
||||
ally_heroSpineData = hero.ally_heroSpineData,
|
||||
ally_heroThemeColor = hero.ally_heroThemeColor,
|
||||
skinDescription = hero.ally_heroDescription,
|
||||
ownerHero = hero,
|
||||
sourceSkin = null
|
||||
};
|
||||
}
|
||||
|
||||
public static string BuildBaseSkinId(int heroId)
|
||||
{
|
||||
return "hero_" + heroId + "_base";
|
||||
}
|
||||
|
||||
public static List<HeroSkinSO> GetExtraSkinsForHero(int heroId)
|
||||
{
|
||||
EnsureCacheBuilt();
|
||||
if (heroId <= 0)
|
||||
{
|
||||
return new List<HeroSkinSO>();
|
||||
}
|
||||
|
||||
if (!CachedByHeroId.TryGetValue(heroId, out List<HeroSkinSO> list) || list == null)
|
||||
{
|
||||
return new List<HeroSkinSO>();
|
||||
}
|
||||
|
||||
return new List<HeroSkinSO>(list);
|
||||
}
|
||||
|
||||
public static HeroSkinSO[] LoadAllHeroSkinAssets()
|
||||
{
|
||||
EnsureCacheBuilt();
|
||||
return cachedAllSkins ?? Array.Empty<HeroSkinSO>();
|
||||
}
|
||||
|
||||
private static HeroSkinResolvedData BuildExtraSkin(AllyHero_SO hero, HeroSkinSO skin)
|
||||
{
|
||||
return new HeroSkinResolvedData
|
||||
{
|
||||
skinId = skin.GetResolvedSkinId(),
|
||||
heroId = hero != null ? hero.ally_heroID : skin.heroId,
|
||||
skinName = string.IsNullOrWhiteSpace(skin.skinName) ? skin.name : skin.skinName,
|
||||
ally_heroDesignation = string.IsNullOrWhiteSpace(skin.ally_heroDesignation) && hero != null ? hero.ally_heroDesignation : skin.ally_heroDesignation,
|
||||
isBaseSkin = false,
|
||||
isDefaultSkin = skin.isDefaultSkin,
|
||||
unlockedByDefault = skin.unlockedByDefault,
|
||||
sourceDlcId = skin.sourceDlcId ?? string.Empty,
|
||||
sortOrder = skin.sortOrder,
|
||||
ally_heroImage = skin.ally_heroImage,
|
||||
ally_heroProfile = skin.ally_heroProfile,
|
||||
ally_heroSelectIcon = skin.ally_heroSelectIcon,
|
||||
ally_heroIcon = skin.ally_heroIcon,
|
||||
ally_heroPoster = skin.ally_heroPoster,
|
||||
ally_hero_HD_image = skin.ally_hero_HD_image,
|
||||
ally_hero_squareProfile = skin.ally_hero_squareProfile,
|
||||
ally_heroSpineData = skin.ally_heroSpineData,
|
||||
ally_heroThemeColor = skin.ally_heroThemeColor,
|
||||
skinDescription = skin.skinDescription,
|
||||
ownerHero = hero,
|
||||
sourceSkin = skin
|
||||
};
|
||||
}
|
||||
|
||||
private static int CompareResolvedSkin(HeroSkinResolvedData left, HeroSkinResolvedData right)
|
||||
{
|
||||
if (ReferenceEquals(left, right))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (left == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (right == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (left.isBaseSkin != right.isBaseSkin)
|
||||
{
|
||||
return left.isBaseSkin ? -1 : 1;
|
||||
}
|
||||
|
||||
int sortCompare = left.sortOrder.CompareTo(right.sortOrder);
|
||||
if (sortCompare != 0)
|
||||
{
|
||||
return sortCompare;
|
||||
}
|
||||
|
||||
return string.CompareOrdinal(left.skinId ?? string.Empty, right.skinId ?? string.Empty);
|
||||
}
|
||||
|
||||
private static void EnsureCacheBuilt()
|
||||
{
|
||||
if (cachedAllSkins != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cachedAllSkins = LoadAllHeroSkinsInternal();
|
||||
CachedByHeroId.Clear();
|
||||
|
||||
for (int i = 0; i < cachedAllSkins.Length; i++)
|
||||
{
|
||||
HeroSkinSO skin = cachedAllSkins[i];
|
||||
if (skin == null || skin.heroId <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!CachedByHeroId.TryGetValue(skin.heroId, out List<HeroSkinSO> list) || list == null)
|
||||
{
|
||||
list = new List<HeroSkinSO>();
|
||||
CachedByHeroId[skin.heroId] = list;
|
||||
}
|
||||
|
||||
list.Add(skin);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<int, List<HeroSkinSO>> pair in CachedByHeroId)
|
||||
{
|
||||
pair.Value.Sort(CompareSkinAsset);
|
||||
}
|
||||
}
|
||||
|
||||
private static int CompareSkinAsset(HeroSkinSO left, HeroSkinSO right)
|
||||
{
|
||||
if (ReferenceEquals(left, right))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (left == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (right == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sortCompare = left.sortOrder.CompareTo(right.sortOrder);
|
||||
if (sortCompare != 0)
|
||||
{
|
||||
return sortCompare;
|
||||
}
|
||||
|
||||
return string.CompareOrdinal(left.GetResolvedSkinId(), right.GetResolvedSkinId());
|
||||
}
|
||||
|
||||
private static HeroSkinSO[] LoadAllHeroSkinsInternal()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
string[] searchFolders = { EditorSearchFolder };
|
||||
string[] guids = AssetDatabase.FindAssets("t:HeroSkinSO", searchFolders);
|
||||
if (guids != null && guids.Length > 0)
|
||||
{
|
||||
List<HeroSkinSO> result = new List<HeroSkinSO>(guids.Length);
|
||||
for (int i = 0; i < guids.Length; i++)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
|
||||
HeroSkinSO skin = AssetDatabase.LoadAssetAtPath<HeroSkinSO>(assetPath);
|
||||
if (skin != null)
|
||||
{
|
||||
result.Add(skin);
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
string[] fallbackGuids = AssetDatabase.FindAssets("t:HeroSkinSO");
|
||||
List<HeroSkinSO> fallback = new List<HeroSkinSO>(fallbackGuids.Length);
|
||||
for (int i = 0; i < fallbackGuids.Length; i++)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(fallbackGuids[i]);
|
||||
HeroSkinSO skin = AssetDatabase.LoadAssetAtPath<HeroSkinSO>(assetPath);
|
||||
if (skin != null)
|
||||
{
|
||||
fallback.Add(skin);
|
||||
}
|
||||
}
|
||||
|
||||
return fallback.ToArray();
|
||||
}
|
||||
#endif
|
||||
|
||||
HeroSkinSO[] loaded = RuntimeResourcesCache.LoadAllHeroSkins();
|
||||
if (loaded != null && loaded.Length > 0)
|
||||
{
|
||||
return loaded;
|
||||
}
|
||||
|
||||
return Resources.LoadAll<HeroSkinSO>(string.Empty) ?? Array.Empty<HeroSkinSO>();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user