using System.Collections.Generic;
using UnityEngine;
namespace Architecture.Core
{
///
/// 运行时集合:替代 FindObjectsOfType / 单例列表,零单例开销地跟踪场景实体。
/// 实体在 OnEnable 注册、OnDisable 注销(见下方 RuntimeSetRegistrar)。
/// 资产实例是项目级资源,跨场景存活,可安全被任何系统读取。
///
public abstract class RuntimeSet : ScriptableObject
{
public List Items = new List();
public void Add(T item)
{
if (item != null && !Items.Contains(item)) Items.Add(item);
}
public void Remove(T item)
{
if (item != null && Items.Contains(item)) Items.Remove(item);
}
public int Count => Items.Count;
public T this[int i] => Items[i];
}
///
/// 通用 Transform 集合,作为"当前场景实体"的轻量注册表(玩家、敌人等)。
/// 领域专用集合(如 EnemyRuntimeSet : RuntimeSet<EnemyAI>)放在对应领域文件夹,
/// 继承本类即可,无需改动核心。
///
[CreateAssetMenu(menuName = "Architecture/Runtime Sets/Transform Set", fileName = "NewTransformSet")]
public class TransformRuntimeSet : RuntimeSet { }
///
/// 挂载到任意预制体,使其自动注册进指定 RuntimeSet。
/// 这样系统只需遍历集合,永不需要 GameObject.Find / FindObjectsOfType。
///
public class RuntimeSetRegistrar : MonoBehaviour
{
[SerializeField] private TransformRuntimeSet _set;
private void OnEnable()
{
if (_set != null) _set.Add(transform);
}
private void OnDisable()
{
if (_set != null) _set.Remove(transform);
}
}
///
/// 泛型注册器:领域专用强类型集合(如 EnemyRuntimeSet : RuntimeSet<EnemyAI>)使用。
/// 自动 GetComponent<T>() 并加入对应集合,避免用 Transform 集合再手动转型。
/// 因 Unity 对泛型 MonoBehaviour 需具体闭包类型才能挂载,领域文件夹内写一行具体子类即可:
/// public class EnemySetRegistrar : RuntimeSetRegistrar<EnemyAI> { }
///
public class RuntimeSetRegistrar : MonoBehaviour where T : Component
{
[SerializeField] private RuntimeSet _set;
private void OnEnable()
{
if (_set != null) _set.Add(GetComponent());
}
private void OnDisable()
{
if (_set != null) _set.Remove(GetComponent());
}
}
}