Files
bansonic_beta_main/Assets/playerInfoDisplay/uAchievement/uAchievementDisplayController.cs
T

218 lines
6.3 KiB
C#

using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class uAchievementDisplayController : MonoBehaviour
{
[Header("prefabs")]
public GameObject uAchievePrefab;
public Transform contentParent;
[Header("sprite list")]
public Sprite[] achievementSprites;
[Header("global achievement")]
public bool initializeGlobalAchievementServiceOnEnable = true;
public string runtimeResourcesPath = GlobalAchievementService.DefaultResourcesPath;
public string editorAssetFolder = GlobalAchievementService.DefaultEditorAssetFolder;
public List<GlobalAchievementSO> scannedGlobalAchievements = new List<GlobalAchievementSO>();
private void OnEnable()
{
if (initializeGlobalAchievementServiceOnEnable)
{
GlobalAchievementService.EnsureInstance().LoadDefinitionsFromResources(runtimeResourcesPath);
}
if (Application.isPlaying)
{
RefreshAchievementInstances();
}
}
#if UNITY_EDITOR
private void OnValidate()
{
if (Application.isPlaying)
{
return;
}
ScanGlobalAchievementsInEditor();
}
#endif
public List<GlobalAchievementSnapshot> GetGlobalAchievementSnapshots()
{
return GlobalAchievementService.EnsureInstance().GetSnapshots();
}
private void Start()
{
if (Application.isPlaying)
{
RefreshAchievementInstances();
}
}
[ContextMenu("Scan Global Achievements")]
public void ScanGlobalAchievements()
{
#if UNITY_EDITOR
if (!Application.isPlaying)
{
ScanGlobalAchievementsInEditor();
return;
}
#endif
scannedGlobalAchievements.Clear();
GlobalAchievementSO[] loaded = Resources.LoadAll<GlobalAchievementSO>(runtimeResourcesPath);
if (loaded == null || loaded.Length == 0)
{
return;
}
scannedGlobalAchievements.AddRange(loaded);
}
public void RefreshAchievementInstances()
{
if (uAchievePrefab == null || contentParent == null)
{
return;
}
ClearAchievementInstances();
List<GlobalAchievementSnapshot> snapshots = GetGlobalAchievementSnapshots();
List<GlobalAchievementSnapshot> displaySnapshots = BuildHighestUnlockedSnapshotsPerSeries(snapshots);
displaySnapshots.Sort(CompareSnapshots);
for (int i = 0; i < displaySnapshots.Count; i++)
{
GlobalAchievementSnapshot snapshot = displaySnapshots[i];
if (!snapshot.unlocked || snapshot.definition == null)
{
continue;
}
GameObject instance = Instantiate(uAchievePrefab, contentParent);
uAchievementPrefab controller = instance.GetComponent<uAchievementPrefab>();
if (controller == null)
{
continue;
}
controller.Setup(snapshot, GetBottomSprite(snapshot.definition.achievementLevel));
}
}
private static List<GlobalAchievementSnapshot> BuildHighestUnlockedSnapshotsPerSeries(List<GlobalAchievementSnapshot> snapshots)
{
var result = new List<GlobalAchievementSnapshot>();
var bestBySeries = new Dictionary<string, GlobalAchievementSnapshot>();
for (int i = 0; i < snapshots.Count; i++)
{
GlobalAchievementSnapshot snapshot = snapshots[i];
if (!snapshot.unlocked || snapshot.definition == null)
{
continue;
}
string seriesKey = !string.IsNullOrWhiteSpace(snapshot.definition.achievementSeriesKey)
? snapshot.definition.achievementSeriesKey
: snapshot.definition.metricType.ToString();
GlobalAchievementSnapshot currentBest;
if (!bestBySeries.TryGetValue(seriesKey, out currentBest))
{
bestBySeries[seriesKey] = snapshot;
continue;
}
int levelCompare = snapshot.definition.achievementLevel.CompareTo(currentBest.definition.achievementLevel);
if (levelCompare > 0)
{
bestBySeries[seriesKey] = snapshot;
continue;
}
if (levelCompare == 0 && snapshot.unlockedUtc < currentBest.unlockedUtc)
{
bestBySeries[seriesKey] = snapshot;
}
}
foreach (var pair in bestBySeries)
{
result.Add(pair.Value);
}
return result;
}
private void ClearAchievementInstances()
{
for (int i = contentParent.childCount - 1; i >= 0; i--)
{
Transform child = contentParent.GetChild(i);
if (Application.isPlaying)
{
Destroy(child.gameObject);
}
else
{
DestroyImmediate(child.gameObject);
}
}
}
private Sprite GetBottomSprite(int level)
{
if (achievementSprites == null || achievementSprites.Length == 0)
{
return null;
}
int safeIndex = Mathf.Clamp(level, 0, achievementSprites.Length - 1);
return achievementSprites[safeIndex];
}
private static int CompareSnapshots(GlobalAchievementSnapshot left, GlobalAchievementSnapshot right)
{
int levelCompare = right.definition.achievementLevel.CompareTo(left.definition.achievementLevel);
if (levelCompare != 0)
{
return levelCompare;
}
return left.unlockedUtc.CompareTo(right.unlockedUtc);
}
#if UNITY_EDITOR
private void ScanGlobalAchievementsInEditor()
{
scannedGlobalAchievements.Clear();
if (string.IsNullOrWhiteSpace(editorAssetFolder))
{
return;
}
string[] guids = AssetDatabase.FindAssets("t:GlobalAchievementSO", new[] { editorAssetFolder });
for (int i = 0; i < guids.Length; i++)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
GlobalAchievementSO definition = AssetDatabase.LoadAssetAtPath<GlobalAchievementSO>(assetPath);
if (definition != null)
{
scannedGlobalAchievements.Add(definition);
}
}
}
#endif
}