feat(identity): add entity identity registry and archive listing

This commit is contained in:
Alexa Amundson
2025-11-25 15:44:22 -06:00
parent ffc2842bd0
commit 4e7418ed4b
4 changed files with 212 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using BlackRoad.Worldbuilder.Identity;
namespace BlackRoad.Worldbuilder.Archive
{
/// <summary>
/// Displays a simple list of all registered identities in the world.
/// Intended to sit under the Archive panel.
/// </summary>
public class IdentityListUI : MonoBehaviour
{
[SerializeField] private Text listText;
[SerializeField] private bool groupByType = true;
[Header("Refresh")]
[SerializeField] private float refreshInterval = 2f;
private float _timer;
private void Update()
{
_timer += Time.deltaTime;
if (_timer >= refreshInterval)
{
_timer = 0f;
Refresh();
}
}
public void Refresh()
{
if (listText == null) return;
var registry = WorldIdentityRegistry.Instance;
if (registry == null)
{
listText.text = "No registry found.";
return;
}
var ids = registry.Identities;
if (ids == null || ids.Count == 0)
{
listText.text = "No entities registered.";
return;
}
var sb = new StringBuilder();
if (groupByType)
{
foreach (WorldIdentity.EntityType type in System.Enum.GetValues(typeof(WorldIdentity.EntityType)))
{
bool any = false;
foreach (var id in ids)
{
if (id == null || id.Type != type) continue;
if (!any)
{
any = true;
sb.AppendLine($"== {type} ==");
}
sb.AppendLine($"- {id.DisplayName} ({id.UniqueId.Substring(0, 6)}...)");
}
if (any) sb.AppendLine();
}
}
else
{
foreach (var id in ids)
{
if (id == null) continue;
sb.AppendLine($"{id.Type}: {id.DisplayName} ({id.UniqueId.Substring(0, 6)}...)");
}
}
listText.text = sb.ToString();
}
}
}

View File

@@ -0,0 +1,46 @@
using UnityEngine;
namespace BlackRoad.Worldbuilder.Identity
{
/// <summary>
/// Assigns a stable identity to an entity in the world.
/// Used by the registry and archive to track critters, villagers, etc.
/// </summary>
public class WorldIdentity : MonoBehaviour
{
public enum EntityType
{
Unknown,
Critter,
Villager,
Structure,
Landmark,
Player
}
[Header("Identity")]
[SerializeField] private string uniqueId;
[SerializeField] private string displayName = "Entity";
[SerializeField] private EntityType type = EntityType.Unknown;
public string UniqueId => uniqueId;
public string DisplayName => displayName;
public EntityType Type => type;
#if UNITY_EDITOR
private void OnValidate()
{
// If no ID assigned, generate a pseudo GUID once in editor
if (string.IsNullOrEmpty(uniqueId))
{
uniqueId = System.Guid.NewGuid().ToString("N");
}
if (string.IsNullOrEmpty(displayName))
{
displayName = gameObject.name;
}
}
#endif
}
}

View File

@@ -0,0 +1,28 @@
using UnityEngine;
namespace BlackRoad.Worldbuilder.Identity
{
/// <summary>
/// Helper that automatically registers a WorldIdentity with the registry.
/// </summary>
[RequireComponent(typeof(WorldIdentity))]
public class WorldIdentityAutoRegister : MonoBehaviour
{
private WorldIdentity _identity;
private void Awake()
{
_identity = GetComponent<WorldIdentity>();
}
private void OnEnable()
{
WorldIdentityRegistry.Instance?.Register(_identity);
}
private void OnDisable()
{
WorldIdentityRegistry.Instance?.Unregister(_identity);
}
}
}

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
using UnityEngine;
namespace BlackRoad.Worldbuilder.Identity
{
/// <summary>
/// Keeps track of all WorldIdentity components currently active in the scene.
/// Provides lookup and lists for Archive/UI.
/// </summary>
public class WorldIdentityRegistry : MonoBehaviour
{
public static WorldIdentityRegistry Instance { get; private set; }
private readonly List<WorldIdentity> _identities = new List<WorldIdentity>();
public IReadOnlyList<WorldIdentity> Identities => _identities;
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
public void Register(WorldIdentity identity)
{
if (identity != null && !_identities.Contains(identity))
{
_identities.Add(identity);
}
}
public void Unregister(WorldIdentity identity)
{
if (identity != null)
{
_identities.Remove(identity);
}
}
public IEnumerable<WorldIdentity> GetByType(WorldIdentity.EntityType type)
{
foreach (var id in _identities)
{
if (id != null && id.Type == type)
yield return id;
}
}
}
}