Задать вопрос
PragmaGames
@PragmaGames
Увлекаюсь Unity.

Как получить все объекты на сцене унаследованные от MonoBehavior?

Всем привет. Решил написать свой простой Di Container. Пока что чисто на MonoBehavior. Я могу раздавать зависимости методам которые помеченные моим атрибутом. Лист хранит привязки. Теперь мне нужно получить все MonoBehaviour на сцене что бы раздать им зависимости. Как это сделать ? Понятно что все эти объекты можно найти через find. Но сам unity должен хранить список всех MonoBehavior объектов что бы работать с ними в режиме плей мода

public class Container : MonoBehaviour
    {
        [SerializeField] private List<MonoBehaviour> _containerList;
        
        private const BindingFlags FLAGS = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

        private void Awake()
        {
            InjectDependencies();
        }

        private void InjectDependencies()
        {
            foreach (var item in _containerList)
            {
                InjectAll(item);
            }
        }

        private void InjectAll(MonoBehaviour target)
        {
            var typeTarget = target.GetType();
            var methods = typeTarget.GetMethods(FLAGS).Where(method => method.IsDefined(typeof(Inject))).ToArray();
            
            InjectAllMethods(target, methods);
        }

        private void InjectAllMethods(MonoBehaviour target, IEnumerable<MethodInfo> methodsInfo)
        {
            foreach (var methodInfo in methodsInfo)
            {
                InjectMethod(target, methodInfo);
            }
        }

        private void InjectMethod(MonoBehaviour target, MethodBase methodInfo)
        {
            var parametersInfo = methodInfo.GetParameters();
            var parameters = new object[parametersInfo.Length];

            var index = 0;
            
            foreach (var parameterInfo in parametersInfo)
            {
                if (TryGetDependencyByType(parameterInfo.ParameterType, out var foundDependency))
                {
                    parameters[index] = foundDependency;
                    index++;
                }
                else
                {
                    return;
                }
            }

            methodInfo?.Invoke(target, parameters);
        }
        
        private bool TryGetDependencyByType(Type type, out MonoBehaviour dependency)
        {
            foreach (var item in _containerList)
            {
                if (item.GetType() == type)
                {
                    dependency = item;
                    return true;
                }
            }

            dependency = null;
            return false;
        }  
    }

[AttributeUsage(AttributeTargets.Method)]
public class Inject : Attribute
{
        
}
  • Вопрос задан
  • 75 просмотров
Подписаться 1 Средний 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
freeExec
@freeExec
Участник OpenStreetMap
Понятно что все эти объекты можно найти через find.

Только так.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы