Каков наиболее предпочтительный метод поиска всех объектов с компонентом X в Unity?
Это достаточно простой вопрос, на который у меня нет ответа.
Задача, необходимо найти все объекты с компонентом X, которые уже существуют на сцене. То есть, просто кэшировать их в какой то условных момент работы условной фабрики XFactory нельзя, ее просто нет.
Известные мне варианты решения проблемы:
-FindObjectsOfType: этот способ поруган всеми кому было не лень, на нем не останавливаюсь.
-FindGameObjectsWithTag: слышал, что чуть быстрее, однако чтобы не расставлять теги вручную, нужно еще не забыть в компонент X поместить метод с установкой тега. Так же, если компонентов желающих установить свой тег несколько, начнутся проблемы.
-Добавление компонентами самих себя в общее хранилище: это то что пытался сделать я, но оступился на том, что нет ни одного разумного способа убедиться, что в хранилище добавились все компоненты. Можно уповать на Awake, но это плохо скажется на порядке инициализации, да и доверять все порядку Unity мало желания. Наиболее хорошее, хоть и жутко громоздкое решение вышло, если улучшить хранилище тем, чтобы оно у каждого кто хочет что то из него взять, до кучи просило Action, в который будет при вызываться если появятся новые объекты, которые не успели о себе сообщить.
Все вышеперечисленное так или иначе либо кажется костылем, либо просто неэффективно.
Итак, знает ли кто то лучшие методы решения этой проблемы?
Текущий(он же последний упомянутый) вариант:
public class WorldArchive
{
private Dictionary<Type, List<object>> _archive;
private Dictionary<Type, List<Action<object>>> _newDataEvents;
public WorldArchive()
{
_archive = new Dictionary<Type, List<object>>();
_newDataEvents = new Dictionary<Type, List<Action<object>>>();
}
public void PutData<T>(T data)
{
if (!_archive.ContainsKey(typeof(T)))
{
_archive[typeof(T)] = new List<object>();
}
_archive[typeof(T)].Add(data);
if(_newDataEvents.ContainsKey(typeof(T)))
{
foreach(Action<object> act in _newDataEvents[typeof(T)])
{
act(data);
}
}
}
public List<T> TakeOutData<T>(Action<T> onNewData)
{
if (!_newDataEvents.ContainsKey(typeof(T)))
{
_newDataEvents[typeof(T)] = new List<Action<object>>();
}
_newDataEvents[typeof(T)].Add(onNewData as Action<object>);
if (!_archive.ContainsKey(typeof(T)))
{
return new List<T>();
}
return _archive[typeof(T)] as List<T>;
}
}