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