Каков наиболее предпочтительный метод поиска всех объектов с компонентом 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>;
    }
}

Ответы (0 шт):