{"id":28,"date":"2021-07-19T16:28:54","date_gmt":"2021-07-19T16:28:54","guid":{"rendered":"https:\/\/docs.sisus.co\/inity\/?p=28"},"modified":"2025-08-23T06:48:53","modified_gmt":"2025-08-23T06:48:53","slug":"monobehaviour-t","status":"publish","type":"post","link":"https:\/\/docs.sisus.co\/init-args\/clients\/monobehaviour-t\/","title":{"rendered":"1. MonoBehaviour&lt;T&#8230;&gt;"},"content":{"rendered":"<h2><img loading=\"lazy\" class=\"alignnone size-full wp-image-682\" src=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/initializable-init-section.png\" alt=\"\" width=\"391\" height=\"91\" srcset=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/initializable-init-section.png 391w, https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/initializable-init-section-300x70.png 300w\" sizes=\"(max-width: 391px) 100vw, 391px\" \/><\/h2>\n<p>Init(args) extends the MonoBehaviour class with the\u00a0ability to receive up to twelve arguments during its initialization, before any of its lifetime events are executed.<\/p>\n<p>To enable your component to receive objects passed to it from the outside, make the class derive from <code>MonoBehaviour&lt;&gt;<\/code>, and list the types of all the objects needed as generic type arguments of the base class. Next implement the Init method, where all the required objects will be received.<\/p>\n<p>In the example below, the <code>Player<\/code> object can receive three objects during its initialization: <code>IInputManager<\/code>, <code>Camera<\/code> and <code>Collider<\/code>.<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">using<\/span> Sisus<span style=\"color: #308080;\">.<\/span>Init<span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">using<\/span> UnityEngine<span style=\"color: #406080;\">;<\/span><\/span>\r\n\r\n<span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">Player<\/span> <span style=\"color: #308080;\">:<\/span> MonoBehaviour<span style=\"color: #308080;\">&lt;<\/span>IInputManager<span style=\"color: #308080;\">,<\/span> Camera<span style=\"color: #308080;\">,<\/span> Collider<span style=\"color: #308080;\">&gt;<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">{<\/span><\/span>\r\n<span class=\"line_wrapper\">   IInputManager inputManager<span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">   Camera camera<span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">   Collider collider<span style=\"color: #406080;\">;<\/span><\/span>\r\n\r\n<span class=\"line_wrapper\">   <span style=\"color: #200080; font-weight: bold;\">protected<\/span> <span style=\"color: #200080; font-weight: bold;\">override<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> <span style=\"color: #005fd2;\">Init<\/span><span style=\"color: #308080;\">(<\/span>IInputManager inputManager<span style=\"color: #308080;\">,<\/span> Camera camera<span style=\"color: #308080;\">,<\/span> Collider collider<span style=\"color: #308080;\">)<\/span><\/span>\r\n<span class=\"line_wrapper\">   <span style=\"color: #406080;\">{<\/span><\/span>\r\n<span class=\"line_wrapper\">      <span style=\"color: #200080; font-weight: bold;\">this<\/span><span style=\"color: #308080;\">.<\/span>inputManager <span style=\"color: #308080;\">=<\/span> inputManager<span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">      <span style=\"color: #200080; font-weight: bold;\">this<\/span><span style=\"color: #308080;\">.<\/span>camera <span style=\"color: #308080;\">=<\/span> camera<span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">      <span style=\"color: #200080; font-weight: bold;\">this<\/span><span style=\"color: #308080;\">.<\/span>collider <span style=\"color: #308080;\">=<\/span> collider<span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">   <span style=\"color: #406080;\">}<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">}<\/span><\/span><\/pre>\n<p>The Init function gets executed when the object is being initialized, before the <a href=\"https:\/\/docs.unity3d.com\/6000.0\/Documentation\/ScriptReference\/MonoBehaviour.Awake.html\">Awake<\/a> or <a href=\"https:\/\/docs.unity3d.com\/6000.0\/Documentation\/ScriptReference\/MonoBehaviour.OnEnable.html\">OnEnable<\/a> events.<\/p>\n<h2>Initialization Logic<\/h2>\n<p>The below chart describes how each <strong>Init<\/strong> method argument is resolved when a client that derives from <code>MonoBehaviour&lt;T...&gt;<\/code> is being loaded:<\/p>\n<p><a href=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/init-arg.png\" target=\"_blank\" rel=\"noopener\"><br \/>\n<img loading=\"lazy\" class=\"alignnone size-full wp-image-1017\" src=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/init-arg.png\" alt=\"Client Initialization Flowchart\" width=\"3840\" height=\"934\" \/><br \/>\n<\/a><\/p>\n<p>Additionally, if <a href=\"https:\/\/docs.sisus.co\/init-args\/getting-started\/initializing-components-in-code\/\">arguments are passed in code<\/a> via <code>AddComponent<\/code> or <code>Instantiate<\/code>, then those will be passed to the Init method instead.<\/p>\n<h2>Asynchronous Initialization<\/h2>\n<p>By default, if any services that a component depends on are not available when the component is being loaded, the execution of all its lifetime events (including Awake, OnEnable and Start) will be deferred until all the services have become available.<\/p>\n<p>This functionality can be disabled for components by adding the <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/init-attribute\/\">[Init] attribute<\/a> to its class and setting <strong>WaitForServices<\/strong> to <strong>false<\/strong>.<\/p>\n<h2 class=\"western\"><span style=\"color: #000000;\"><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: x-large;\"><b>OnAwake<\/b><\/span><\/span><\/span><\/h2>\n<p>The MonoBehaviour&lt;T&#8230;&gt; base class automatically receives Init arguments that have been injected to the object in its <a href=\"https:\/\/docs.unity3d.com\/6000.0\/Documentation\/ScriptReference\/MonoBehaviour.Awake.html\">Awake<\/a> method. It then first passes the received arguments to the Init method, and after that executes the OnAwake method.<\/p>\n<p>If you want to execute code during the Awake lifetime event in a component that derives from MonoBehaviour&lt;T..&gt;, you should override the OnAwake method, instead of defining a new Awake method:<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">Player<\/span> <span style=\"color: #308080;\">:<\/span> MonoBehaviour<span style=\"color: #308080;\">&lt;<\/span>IInputManager<span style=\"color: #308080;\">&gt;<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">{<\/span><\/span>\r\n<span class=\"line_wrapper\">   IInputManager inputManager<span style=\"color: #406080;\">;<\/span><\/span>\r\n\r\n<span class=\"line_wrapper\">   <span style=\"color: #200080; font-weight: bold;\">protected<\/span> <span style=\"color: #200080; font-weight: bold;\">override<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> Init<span style=\"color: #308080;\">(<\/span>IInputManager inputManager<span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> <span style=\"color: #200080; font-weight: bold;\">this<\/span><span style=\"color: #308080;\">.<\/span>inputManager <span style=\"color: #308080;\">=<\/span> inputManager<span style=\"color: #406080;\">;<\/span><\/span>\r\n\r\n<span class=\"line_wrapper\">   <span style=\"color: #200080; font-weight: bold;\">protected<\/span> <span style=\"color: #200080; font-weight: bold;\">override<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> OnAwake<span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> Debug<span style=\"color: #308080;\">.<\/span>Log<span style=\"color: #308080;\">(<\/span><span style=\"color: #800000;\">$\"<\/span><span style=\"color: #1060b6;\">I can use <\/span><span style=\"color: #406080;\">{<\/span><span style=\"color: #005fd2;\">inputManager<\/span><span style=\"color: #406080;\">}<\/span><span style=\"color: #1060b6;\"> in OnAwake!<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">   <span style=\"color: #200080; font-weight: bold;\">void<\/span> OnEnable<span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> Debug<span style=\"color: #308080;\">.<\/span>Log<span style=\"color: #308080;\">(<\/span><span style=\"color: #800000;\">$\"<\/span><span style=\"color: #1060b6;\">I can use <\/span><span style=\"color: #406080;\">{<\/span><span style=\"color: #005fd2;\">inputManager<\/span><span style=\"color: #406080;\">}<\/span><span style=\"color: #1060b6;\"> in OnEnable!<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">   <span style=\"color: #200080; font-weight: bold;\">void<\/span> Start<span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> Debug<span style=\"color: #308080;\">.<\/span>Log<span style=\"color: #308080;\">(<\/span><span style=\"color: #800000;\">$\"<\/span><span style=\"color: #1060b6;\">I can use <\/span><span style=\"color: #406080;\">{<\/span><span style=\"color: #005fd2;\">inputManager<\/span><span style=\"color: #406080;\">}<\/span><span style=\"color: #1060b6;\"> in Start!<\/span><span style=\"color: #800000;\">\"<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">}<\/span><\/span><\/pre>\n<h2 class=\"western\"><span style=\"color: #000000;\"><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: x-large;\"><b>OnReset<\/b><\/span><\/span><\/span><\/h2>\n<p>Similarly, the MonoBehaviour&lt;T&#8230;&gt; base class already defines a <a href=\"https:\/\/docs.unity3d.com\/6000.0\/Documentation\/ScriptReference\/MonoBehaviour.Reset.html\">Reset<\/a> method, to support the <a href=\"https:\/\/docs.sisus.co\/init-args\/features\/initonreset\/\">InitOnReset<\/a> feature.<\/p>\n<p>If you want to execute code during the Reset lifetime event in a component that derives from MonoBehaviour&lt;T..&gt;, you should override the OnReset method, instead of defining a new Reset method:<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">Player<\/span> <span style=\"color: #308080;\">:<\/span> MonoBehaviour<span style=\"color: #308080;\">&lt;<\/span>IInputManager<span style=\"color: #308080;\">&gt;<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">{<\/span><\/span>\r\n<span class=\"line_wrapper\">   IInputManager inputManager<span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">   [SerializeField] Collider collider<span style=\"color: #406080;\">;<\/span><\/span>\r\n\r\n<span class=\"line_wrapper\">   <span style=\"color: #200080; font-weight: bold;\">protected<\/span> <span style=\"color: #200080; font-weight: bold;\">override<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> Init<span style=\"color: #308080;\">(<\/span>IInputManager inputManager<span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> <span style=\"color: #200080; font-weight: bold;\">this<\/span><span style=\"color: #308080;\">.<\/span>inputManager <span style=\"color: #308080;\">=<\/span> inputManager<span style=\"color: #406080;\">;<\/span><\/span>\r\n\r\n<span class=\"line_wrapper\">   <span style=\"color: #200080; font-weight: bold;\">protected<\/span> <span style=\"color: #200080; font-weight: bold;\">override<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> OnReset<span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> collider <span style=\"color: #308080;\">=<\/span> GetComponent<span style=\"color: #308080;\">&lt;<\/span>Collider<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">}<\/span><\/span><\/pre>\n<h2 class=\"western\"><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: x-large;\"><b>AddComponent with Arguments<\/b><\/span><\/span><\/h2>\n<p>Init(args) extends the <a href=\"https:\/\/docs.unity3d.com\/6000.0\/Documentation\/ScriptReference\/GameObject.html\">GameObject<\/a> type with new AddComponent methods that allow passing Init arguments to the created component.<\/p>\n<p>To do so, list the types of the Init parameters after the type of the added component, and pass in the objects you want as arguments of the method:<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\">gameObject<span style=\"color: #308080;\">.<\/span>AddComponent<span style=\"color: #308080;\">&lt;<\/span>Player<span style=\"color: #308080;\">,<\/span> IInputManager<span style=\"color: #308080;\">,<\/span> Camera<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span>inputManager<span style=\"color: #308080;\">,<\/span> camera<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span><\/pre>\n<p>Alternatively, you can use an AddComponent variant which assigns the created component into an out parameter, instead of return it.<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\">gameObject<span style=\"color: #308080;\">.<\/span>AddComponent<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">out<\/span> Player player<span style=\"color: #308080;\">,<\/span> inputManager<span style=\"color: #308080;\">,<\/span> camera<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span><\/pre>\n<p>This is functionally identical, but it can make it possible to omit all the generic type arguments, which can help improve readability. This is possible because the C# compiler can determine the generic type arguments implicitly from the types of the variables that are passed in to the method as arguments.<\/p>\n<p>Note that in order for the C# compiler to be able to do this, the types of the provided variables must match the types of the Init method parameters <strong>exactly<\/strong>. So if, for example, the Player&#8217;s Init method has a parameter of type IInputManager, and you pass in a variable of type InputManager, the C# compiler will not be able to figure out the generic type arguments for the method call automatically. You can however help the compiler to get past this hurdle by <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/types\/casting-and-type-conversions#explicit-conversions\">casting<\/a> the variable to the exact type of the Init method parameter:<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">var<\/span> inputManager <span style=\"color: #308080;\">=<\/span> Service<span style=\"color: #308080;\">.<\/span>GetFor<span style=\"color: #308080;\">&lt;<\/span>InputManager<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span>gameObject<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">gameObject<span style=\"color: #308080;\">.<\/span>AddComponent<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">out<\/span> Player player<span style=\"color: #308080;\">,<\/span> <span style=\"color: #308080;\">(<\/span>IInputManager<span style=\"color: #308080;\">)<\/span>inputManager<span style=\"color: #308080;\">,<\/span> camera<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span><\/pre>\n<p>The AddComponent extension methods can be used automatically with any components that derive from MonoBehaviour&lt;T&#8230;&gt;.<\/p>\n<p>They can also be used with any components that implement <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/iargs\/\">IArgs&lt;T&#8230;&gt;<\/a> and manually receive the injected arguments using <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/initargs\/\">InitArgs.TryGet<\/a> in their Awake or OnEnable method.<\/p>\n<p>It can also be used automatically with any components that implement <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/iinitializable\/\">IInitializable&lt;T&#8230;&gt;<\/a>, even if they don&#8217;t manually receive the injected arguments via InitArgs.TryGet. However, if they <em>don&#8217;t<\/em> receive the arguments manually, then they will only receive them in their Init method <em><strong>after<\/strong><\/em> the Awake and OnEnable events. This means that it is only possible to make use of those services during and after the <a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/MonoBehaviour.Start.html\">Start<\/a> event.<\/p>\n<h2 class=\"western\"><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: x-large;\"><b>Instantiate with Arguments<\/b><\/span><\/span><\/h2>\n<p>Init(args) also extends all components and scriptable objects with new Instantiate methods that allow passing arguments to the created instance.<\/p>\n<p>To clone an Object while passing Init arguments to the clone, call Instantiate on the Object you want cloned, and pass in the Init arguments to the method:<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\">prefab<span style=\"color: #308080;\">.<\/span>Instantiate<span style=\"color: #308080;\">(<\/span>inputManager<span style=\"color: #308080;\">,<\/span> camera<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span><\/pre>\n<h2 class=\"western\"><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: x-large;\"><b>New GameObject with Arguments<\/b><\/span><\/span><\/h2>\n<p>Init(args) also lets you create a new GameObject from scratch, attach a component to it, and pass Init arguments to the component, all in one go.<\/p>\n<p>To do so, use <a href=\"https:\/\/docs.unity3d.com\/6000.0\/Documentation\/ScriptReference\/GameObject-ctor.html\">new GameObject<\/a> like you normally would, but now also include the type of the component you want attached to the GameObject as generic type argument. Then, call the Init method on the object to provide Init arguments to the attached component and finalize the whole process:<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\">var player <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">new<\/span> GameObject<span style=\"color: #308080;\">&lt;<\/span>Player<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #308080;\">.<\/span>Init<span style=\"color: #308080;\">(<\/span>inputManager<span style=\"color: #308080;\">,<\/span> camera<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span><\/pre>\n<p>If you don&#8217;t need to pass any Init arguments to the attached component, you can finalize the process either by calling Init() with no arguments, or by assigning the object into a variable of type GameObject, or of a type matching the attached component:<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">var<\/span> player <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">new<\/span> GameObject<span style=\"color: #308080;\">&lt;<\/span>Player<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #308080;\">.<\/span>Init<span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;\r\n\r\n<\/span><\/span><span class=\"line_wrapper\">Player player <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">new<\/span> GameObject<span style=\"color: #308080;\">&lt;<\/span>Player<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n\r\n<span class=\"line_wrapper\">GameObject gameObject <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">new<\/span> GameObject<span style=\"color: #308080;\">&lt;<\/span>Player<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span><\/pre>\n<p>You can also attach and initialize more than one component (up to three) at the same time, by adding generic type arguments for all the components you want attached.<\/p>\n<p>Then instead of calling Init on the result, you can use Init1, Init2 and Init3 to initialize the first, second and third attached components respectively:<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">new<\/span> GameObject<span style=\"color: #308080;\">&lt;<\/span>Player<span style=\"color: #308080;\">,<\/span> Collider<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #308080;\">.<\/span>Init1<span style=\"color: #308080;\">(<\/span>inputManager<span style=\"color: #308080;\">,<\/span> camera<span style=\"color: #308080;\">,<\/span> Second<span style=\"color: #308080;\">.<\/span>Component<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span><\/pre>\n<p>Once you have provided Init arguments for all the components that need them, you can finalize the whole process by assigning the object into a variable of type GameObject, of a type matching one of the added component, or of a <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/csharp\/language-reference\/builtin-types\/value-tuples\">tuple<\/a> type matching several of the added components:<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\">Player player <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">new<\/span> GameObject<span style=\"color: #308080;\">&lt;<\/span>Player<span style=\"color: #308080;\">,<\/span> Collider<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;\r\n<\/span><\/span>\r\n<span class=\"line_wrapper\">GameObject gameObject <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">new<\/span> GameObject<span style=\"color: #308080;\">&lt;<\/span>Player<span style=\"color: #308080;\">,<\/span> Collider<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;\r\n<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #308080;\">(<\/span>Player player<span style=\"color: #308080;\">,<\/span> Collider collider<span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">new<\/span> GameObject<span style=\"color: #308080;\">&lt;<\/span>Player<span style=\"color: #308080;\">,<\/span> Collider<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span><\/pre>\n<h2>Service Arguments<\/h2>\n<p>If all Init arguments of a component that derives from MonoBehaviour&lt;T&#8230;&gt; are <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/global-services\/\">global<\/a> or <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/local-services\/\">local services<\/a>, then the component will receive all of them automatically during its initialization.<\/p>\n<p>In this case you do not need to need to attach an <a href=\"https:\/\/docs.sisus.co\/init-args\/features\/initializer\/\">Initializer<\/a> to the component when it exists as part of a scene or a prefab.<\/p>\n<p>In this case you can also use the built-in <a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/Object.Instantiate.html\">Instantiate<\/a> and <a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/GameObject.AddComponent.html\">AddComponent<\/a> methods to create instances of the components, without needing to pass in their dependencies manually.<\/p>\n<p>Note that you <em>can<\/em> still attach an Initializer or use Instantiate or AddComponent with arguments to customize the services being provided to specific client instance.<\/p>\n<p>For example, you could make all components use the DefaultLogger class for logging text to the Console by default, but in unit tests pass in a TestLogger using AddComponent with arguments. Or to debug the behaviour of a particular component exhibiting strange behaviour, you could temporarily attach an Initializer to it and configure it to use the more verbose DebugLogger.<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\"><span style=\"color: #308080;\">[<\/span>Service<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">typeof<\/span><span style=\"color: #308080;\">(<\/span>ILogger<span style=\"color: #308080;\">)<\/span><span style=\"color: #308080;\">)<\/span><span style=\"color: #308080;\">]<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">DefaultLogger<\/span> <span style=\"color: #308080;\">:<\/span> ILogger<\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">{<\/span><\/span>\r\n<span class=\"line_wrapper\">    <span style=\"color: #200080; font-weight: bold;\">public<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> <span style=\"color: #005fd2;\">Debug<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">string<\/span> message<span style=\"color: #308080;\">)<\/span> <span style=\"color: #406080;\">{<\/span> <span style=\"color: #406080;\">}<\/span><\/span>\r\n<span class=\"line_wrapper\">    <span style=\"color: #200080; font-weight: bold;\">public<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> Info<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">string<\/span> message<span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> Debug<span style=\"color: #308080;\">.<\/span>Log<span style=\"color: #308080;\">(<\/span>message<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">    <span style=\"color: #200080; font-weight: bold;\">public<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> Error<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">string<\/span> message<span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> Debug<span style=\"color: #308080;\">.<\/span>LogError<span style=\"color: #308080;\">(<\/span>message<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">}<\/span><\/span>\r\n\r\n<span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">DebugLogger<\/span>\u00a0: ILogger<\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">{<\/span><\/span>\r\n<span class=\"line_wrapper\">    <span style=\"color: #200080; font-weight: bold;\">public<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> Debug<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">string<\/span> message<span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> Debug<span style=\"color: #308080;\">.<\/span>Log<span style=\"color: #308080;\">(<\/span>message<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">    <span style=\"color: #200080; font-weight: bold;\">public<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> Info<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">string<\/span> message<span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> Debug<span style=\"color: #308080;\">.<\/span>Log<span style=\"color: #308080;\">(<\/span>message<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">    <span style=\"color: #200080; font-weight: bold;\">public<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> Error<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">string<\/span> message<span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> Debug<span style=\"color: #308080;\">.<\/span>LogError<span style=\"color: #308080;\">(<\/span>message<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">}<\/span><\/span>\r\n\r\n<span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">TestLogger<\/span> <span style=\"color: #308080;\">:<\/span> ILogger<\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">{<\/span><\/span>\r\n<span class=\"line_wrapper\">    <span style=\"color: #200080; font-weight: bold;\">public<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> <span style=\"color: #005fd2;\">Debug<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">string<\/span> message<span style=\"color: #308080;\">)<\/span> <span style=\"color: #406080;\">{<\/span> <span style=\"color: #406080;\">}<\/span><\/span>\r\n<span class=\"line_wrapper\">    <span style=\"color: #200080; font-weight: bold;\">public<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> <span style=\"color: #005fd2;\">Info<\/span><span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">string<\/span> message<span style=\"color: #308080;\">)<\/span> <span style=\"color: #406080;\">{<\/span> <span style=\"color: #406080;\">}<\/span><\/span>\r\n<span class=\"line_wrapper\">    <span style=\"color: #200080; font-weight: bold;\">public<\/span> <span style=\"color: #200080; font-weight: bold;\">void<\/span> Error<span style=\"color: #308080;\">(<\/span><span style=\"color: #200080; font-weight: bold;\">string<\/span> message<span style=\"color: #308080;\">)<\/span> <span style=\"color: #308080;\">=<\/span><span style=\"color: #308080;\">&gt;<\/span> Debug<span style=\"color: #308080;\">.<\/span>LogError<span style=\"color: #308080;\">(<\/span>message<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\"><span style=\"color: #406080;\">}<\/span><\/span><\/pre>\n<h2 class=\"western\"><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: x-large;\"><b>Arguments via the Inspector<\/b><\/span><\/span><\/h2>\n<p>You can also use the Inspector to configure the Init arguments for instances of components that derive from MonoBehaviour&lt;T&#8230;&gt;.<\/p>\n<p>Refer to the <a href=\"https:\/\/docs.sisus.co\/init-args\/features\/initializer\/\">Initializer documentation<\/a> for more information on how to do this.<\/p>\n<h2 class=\"western\"><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: x-large;\"><b>Manually Passing Arguments in Code<\/b><\/span><\/span><\/h2>\n<p>It addition to all the methods listed above for passing Init arguments to components that derive from MonoBehaviour&lt;T&#8230;&gt; during their initialization, it is also possible pass arguments to the Init method manually.<\/p>\n<p><span style=\"font-size: medium;\">One example of a scenario where this might be useful is when using the <a href=\"https:\/\/docs.unity3d.com\/2021.3\/Documentation\/ScriptReference\/Pool.ObjectPool_1.html\">object pool pattern<\/a>, where you might want to initialize reused instances with new Init arguments every time that they are returned from the pool.<\/span><\/p>\n<p>To manually pass in arguments to the Init method, simply cast the component to <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/iinitializable\/\">IInitializable&lt;T&#8230;&gt;<\/a> and execute the Init method on it:<\/p>\n<pre class=\"code_syntax\" style=\"color: #000020; background: #f6f8ff;\"><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">var<\/span> initializable <span style=\"color: #308080;\">=<\/span> <span style=\"color: #308080;\">(<\/span>IInitializable<span style=\"color: #308080;\">&lt;<\/span>IInputManager<span style=\"color: #308080;\">,<\/span> Camera<span style=\"color: #308080;\">&gt;<\/span><span style=\"color: #308080;\">)<\/span>player<span style=\"color: #406080;\">;<\/span><\/span>\r\n<span class=\"line_wrapper\">initializable<span style=\"color: #308080;\">.<\/span>Init<span style=\"color: #308080;\">(<\/span>inputManager<span style=\"color: #308080;\">,<\/span> camera<span style=\"color: #308080;\">)<\/span><span style=\"color: #406080;\">;<\/span><\/span><\/pre>\n<h2 class=\"western\"><span style=\"color: #000000;\"><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: x-large;\"><b>Init Section<\/b><\/span><\/span><\/span><\/h2>\n<p>An Init section is shown by default in the Inspector for all components that derive from MonoBehaviour&lt;T&#8230;&gt;.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-682\" src=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/initializable-init-section.png\" alt=\"\" width=\"391\" height=\"91\" srcset=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/initializable-init-section.png 391w, https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/initializable-init-section-300x70.png 300w\" sizes=\"(max-width: 391px) 100vw, 391px\" \/><\/p>\n<h3>Hiding the Init Section<\/h3>\n<p>If you want to hide the Init section for all components of a particular type, you can do so by adding the <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/init-attribute\/\">[Init] attribute<\/a> to the component&#8217;s class and setting <em>HideInInspector<\/em> to <strong>true<\/strong>:<\/p>\n<pre><span class=\"line_wrapper\">[Init<span style=\"color: #308080;\">(<\/span>HideInInspector <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">true<\/span><span style=\"color: #308080;\">)<\/span>]\r\n<\/span><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">Client<\/span> <span style=\"color: #308080;\">:<\/span> MonoBehaviour<span style=\"color: #308080;\">&lt;<\/span>IInputManager<span style=\"color: #308080;\">&gt;<\/span><\/span><\/pre>\n<p>Alternatively you can do the same using the Inspector by disabling the <em>Show Init Section<\/em> item using the context menu of any component of the type in question:<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-684\" src=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/toggle-show-init-section.png\" alt=\"\" width=\"369\" height=\"294\" srcset=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/toggle-show-init-section.png 369w, https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/toggle-show-init-section-300x239.png 300w\" sizes=\"(max-width: 369px) 100vw, 369px\" \/><\/p>\n<p>This can be useful in situations where Edit Mode configuration is handled via serialized fields, and providing arguments via the Init method is supposed to be optional, and only done when creating instances at runtime using AddComponent (perhaps to facilitate easy unit testing).<\/p>\n<h3 class=\"western\"><span style=\"color: #000000;\"><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: x-large;\"><b>Null Argument Guard <\/b><\/span><\/span><\/span><b style=\"font-size: x-large; font-family: 'Liberation Sans', sans-serif; color: #000000;\">Icon<\/b><\/h3>\n<p>All components that derive from MonoBehaviour&lt;T&#8230;&gt; can validate that they have received all objects that they depend on via the Init method before the OnAwake event. If the Null Argument Guard is active, and a MonoBehaviour&lt;T&#8230;&gt; component is loaded without it having been provided it with its Init arguments, then a <em>MissingInitArgumentsException<\/em> will be thrown.<\/p>\n<p>You can see information about the current state of the Null Argument Guard by mouseovering the Null Argument Guard icon in the Inspector.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-686\" src=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/null-argument-guard-tooltip.png\" alt=\"\" width=\"391\" height=\"140\" srcset=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/null-argument-guard-tooltip.png 391w, https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/null-argument-guard-tooltip-300x107.png 300w\" sizes=\"(max-width: 391px) 100vw, 391px\" \/><\/p>\n<p>The Null Argument Guard is enabled in Edit Mode and at Runtime by default. If you want to adjust the Null Argument Guard used by all components of a particular type, you can do so by adding the <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/init-attribute\/\">[Init] attribute<\/a> to the component&#8217;s class and setting NullArgumentGuard to the desired value:<\/p>\n<pre><span class=\"line_wrapper\">[Init<span style=\"color: #308080;\">(<\/span>ArgumentGuard <span style=\"color: #308080;\">=<\/span> NullArgumentGuard<span style=\"color: #308080;\">.<\/span>None<span style=\"color: #308080;\">)<\/span>]\r\n<\/span><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">Client<\/span> <span style=\"color: #308080;\">:<\/span> MonoBehaviour<span style=\"color: #308080;\">&lt;<\/span>IInputManager<span style=\"color: #308080;\">&gt;<\/span><\/span><\/pre>\n<p>Alternatively you can do the same using the Inspector by clicking the Null Argument Guard icon in the Init section of any component of that particular type, and ticking the Null Argument Guard options that you want to be enabled.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-688\" src=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/null-argument-guard-all-enabled.png\" alt=\"\" width=\"452\" height=\"143\" srcset=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/null-argument-guard-all-enabled.png 452w, https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/null-argument-guard-all-enabled-300x95.png 300w\" sizes=\"(max-width: 452px) 100vw, 452px\" \/><\/p>\n<p>You can also adjust <em>Null Argument Guard<\/em> options individually for specific component instances by attaching an <a href=\"https:\/\/docs.sisus.co\/init-args\/features\/initializer\/\">Initializer<\/a>.<\/p>\n<h3 class=\"western\"><span style=\"color: #000000;\"><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: x-large;\"><b>Add Initializer Icon<\/b><\/span><\/span><\/span><\/h3>\n<p>You can use the plus icon in the Init section to attach an <a href=\"https:\/\/docs.sisus.co\/init-args\/features\/initializer\/\">Initializer<\/a> to the component.<\/p>\n<p>If no initializers exist for the component yet, pressing the icon will prompt you to generate one instead.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-689\" src=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/generate-initializer-button.png\" alt=\"\" width=\"475\" height=\"91\" srcset=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/generate-initializer-button.png 475w, https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/generate-initializer-button-300x57.png 300w\" sizes=\"(max-width: 475px) 100vw, 475px\" \/><\/p>\n<h3 class=\"western\">Default Initializer<\/h3>\n<p>If a component has exactly one Initializer, it will be attached to the component by default when the component is attached to a GameObject in Edit Mode.<\/p>\n<p>You can disable this behaviour by adding the [Init] attribute to the component&#8217;s class and setting <em>DefaultInitializer<\/em> to <strong>null<\/strong>:<\/p>\n<pre><span class=\"line_wrapper\">[Init<span style=\"color: #308080;\">(<\/span>DefaultInitializer <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">null<\/span><span style=\"color: #308080;\">)<\/span>]\r\n<\/span><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">Client<\/span> <span style=\"color: #308080;\">:<\/span> MonoBehaviour<span style=\"color: #308080;\">&lt;<\/span>IInputManager<span style=\"color: #308080;\">&gt;<\/span><\/span><\/pre>\n<p>Alternatively you can add the [Init] attribute to the Initializer class and set <em>DefaultInitializer<\/em> to <strong>false<\/strong>.<\/p>\n<pre><span class=\"line_wrapper\">[Init<span style=\"color: #308080;\">(<\/span>DefaultInitializer <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">false<\/span><span style=\"color: #308080;\">)<\/span>]\r\n<\/span><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">ClientInitializer<\/span> <span style=\"color: #308080;\">:<\/span> Initializer<span style=\"color: #308080;\">&lt;<\/span>Client, IInputManager<span style=\"color: #308080;\">&gt;<\/span><\/span><\/pre>\n<h2 class=\"western\">Wait For Services<\/h2>\n<p>By default the initialization of components that derive from MonoBehaviour&lt;T&#8230;&gt; is automatically delayed until all the services that they depend on have become available.<\/p>\n<p>If this <em>WaitForServices<\/em> behaviour is enabled, and any Init arguments are not available when the component is loaded, the component is disabled until all its services become available. The moment that all Init arguments have become available, they are passed to the component&#8217;s Init method, and the component is enabled, causing the Awake, OnEnable and Start methods to execute.<\/p>\n<p>You can disable this behaviour by adding the [Init] attribute to the component&#8217;s class and setting <em>WaitForServices <\/em>to <strong>false<\/strong>:<\/p>\n<pre><span class=\"line_wrapper\">[Init<span style=\"color: #308080;\">(<\/span>WaitForServices <span style=\"color: #308080;\">=<\/span> <span style=\"color: #200080; font-weight: bold;\">false<\/span><span style=\"color: #308080;\">)<\/span>]\r\n<\/span><span class=\"line_wrapper\"><span style=\"color: #200080; font-weight: bold;\">class<\/span> <span style=\"color: #005fd2;\">Client<\/span> <span style=\"color: #308080;\">:<\/span> MonoBehaviour<span style=\"color: #308080;\">&lt;<\/span>IInputManager<span style=\"color: #308080;\">&gt;<\/span><\/span><\/pre>\n<p>If WaitForServices behaviour is disabled, then the component will only attempt to receive its Init arguments once when it is loaded, and the component will not be disabled even if didn&#8217;t receive its Init arguments.<\/p>\n<p>If runtime exceptions are enabled for the Null Argument Guard, then an exception will be thrown if the component is loaded without receiving its Init arguments.<\/p>\n<h2 class=\"western\">Runtime State<\/h2>\n<p>By default the Unity editor only visualizes serialized fields in the Inspector. This can make it difficult to debug components at runtime, and gain information about whether or not they&#8217;ve acquired all the objects that they depend on.<\/p>\n<p>To account for this, Init(args) augments the Inspector of all components that derive from MonoBehaviour&lt;T&#8230;&gt; with the ability to also see the state of non-serialized members in the Inspector in Play Mode.<\/p>\n<p><img loading=\"lazy\" class=\"alignnone size-full wp-image-551\" src=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/runtime-state.png\" alt=\"\" width=\"392\" height=\"207\" srcset=\"https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/runtime-state.png 392w, https:\/\/docs.sisus.co\/init-args\/wp-content\/uploads\/sites\/6\/2021\/07\/runtime-state-300x158.png 300w\" sizes=\"(max-width: 392px) 100vw, 392px\" \/><\/p>\n<h2 class=\"western\">Init Method Best Practices<\/h2>\n<p>It is generally speaking recommended to not use the Init method for anything else besides assigning the received arguments into member variables.<\/p>\n<p>Lifetime event methods like OnAwake, OnEnable and Start can then be used to execute additional logic that can make use of those services.<\/p>\n<p>There are a couple of reasons for this recommendation:<\/p>\n<ul>\n<li>The Init method can be executed in Edit Mode if the class has the <a href=\"https:\/\/docs.sisus.co\/init-args\/features\/initonreset\/\">[InitOnReset]<\/a>\u00a0or <a href=\"https:\/\/docs.sisus.co\/init-args\/features\/init-in-edit-mode\/\">[InitInEditMode]<\/a> attribute.<\/li>\n<li>The Init method can be executed by InactiveInitializer while the GameObject is still inactive, if this behaviour has been selected using the Inspector.<\/li>\n<li>The Init method can be executed by an Initializer while the component is still disabled when there&#8217;s a need to wait for an async service or <a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/ivalueprovider\/\">value provider<\/a>.<\/li>\n<li>The Init method can be executed by <em>new GameObject&lt;T&gt;<\/em> while the GameObject is still inactive, in order to defer component lifetime events from executing until initialization arguments have been passed to all the attached components.<\/li>\n<li><a href=\"https:\/\/docs.sisus.co\/init-args\/reference\/initargs\/\">InitArgs.TryGet<\/a> is thread-safe, and can theoretically be used to receive injected Init arguments even in the constructor or during the <a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/ISerializationCallbackReceiver.OnAfterDeserialize.html\">OnAfterDeserialize<\/a> event. If this is done, then the Init method could get executed from a background thread, and before deserialization has finished for the whole GameObject.<\/li>\n<\/ul>\n<p>All these things mean that there can be particular situations where doing things beyond just assigning arguments to members in an Init method might result in undesired behaviour such as:<\/p>\n<ul>\n<li>Methods getting executed on components in Edit Mode.<\/li>\n<li>Methods getting executed on components before the OnAwake, OnEnable, Start methods have been executed.<\/li>\n<li>StartCoroutine call failing with an error due to the GameObject still being inactive.<\/li>\n<li>Calls to Unity method failing with an error due to being called during the deserialization process.<\/li>\n<\/ul>\n<p>Of course, this is just a general recommendation, and there can be situations it makes sense to not follow it. For example, <a href=\"https:\/\/docs.unity3d.com\/ScriptReference\/Behaviour-enabled.html\">enabling<\/a> a component at the end of its Init method can sometimes be a useful pattern with components that need to be disabled until they&#8217;ve received an asynchronously loaded service or value provider value.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Init(args) extends the MonoBehaviour class with the\u00a0ability to receive up to twelve arguments during its initialization, before any of its lifetime events are executed. To enable your component to receive objects passed to it from the outside, make the class derive from MonoBehaviour&lt;&gt;, and list the types of all the objects needed as generic type ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"https:\/\/docs.sisus.co\/init-args\/clients\/monobehaviour-t\/\" title=\"read more\">Read more<\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[10],"tags":[],"_links":{"self":[{"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts\/28"}],"collection":[{"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/comments?post=28"}],"version-history":[{"count":50,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts\/28\/revisions"}],"predecessor-version":[{"id":1028,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/posts\/28\/revisions\/1028"}],"wp:attachment":[{"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/media?parent=28"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/categories?post=28"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/docs.sisus.co\/init-args\/wp-json\/wp\/v2\/tags?post=28"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}