拼ui 一些业务逻辑x实现
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user