P
P
Pragma Games2022-02-06 11:43:40
Unity
Pragma Games, 2022-02-06 11:43:40

How to get all objects on the stage inherited from MonoBehavior?

Hello. I decided to write my own simple Di Container. So far purely on MonoBehavior. I can distribute dependencies to methods that are marked with my attribute. The sheet stores bindings. Now I need to get all the MonoBehaviours on the stage in order to distribute dependencies to them. How to do it ? It is clear that all these objects can be found through find. But unity itself must store a list of all MonoBehavior objects in order to work with them in play mode

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
{
        
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
F
freeExec, 2022-02-06
@freeExec

It is clear that all these objects can be found through find.

The only way.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question