08. InitInEditMode

  04. Features No Comments

Add this attribute to a component to have the arguments accepted by it be automatically gathered and passed to its Init function in Edit Mode, whenever any objects in the same scene or prefab that contains the component are modified.

This attribute supports any components that implement IInitializable<T>, which includes all classes that derive from MonoBehaviour<T>.

Dependencies for the component are automatically retrieved from the scene hierarchy, relative to the GameObject that holds the component with the attribute.

You can specify from where Object arguments should be searched, or use the default search mode, which tries to pick a good search mode to use based on the type of the argument:

  • Transform or GameObject: From.GameObject
  • Other Component or interface: From.Children or From.Parent or From.SameScene
  • Other Object: From.Assets
  • Collection of Component, interface, Transform or GameObject: From.Children
    • For example Collider[] or IEnumerable<Transform>

The found arguments are passed to the component’s IInitializable<>.Init function,
where they can be assigned to serialized fields.

This behaviour only occurs in edit mode and is meant to make it more convenient to add components without needing to assign all Object references manually using the inspector.

Example

For example, the following Player component would get its Init method automatically called in Edit Mode with the nearest Collider and AnimatorController components found in the same scene or prefab that holds the component (if both are found):

[InitInEditMode]
public class Player : MonoBehaviour<Collider, AnimatorController>
{
    [SerializeField]
    private Collider collider;

    [SerializeField]
    private AnimatorController animatorController;

    protected override void Init(Collider collider,
                                 AnimatorController animatorController)
    {
        this.collider = collider;
        this.animatorController = animatorController;
    }
}

By default component argument values are retrieved using the following logic:

  1. First the same GameObject is searched for a component of the required type.
  2. Second all child GameObjects are searched for a component of the required type.
  3. Third all parent GameObjects are searched for a component of the required type.
  4. Lastly all GameObjects in the same scene are searched for a component of the required type.

For each required component type the first match that is found using this search order is retrieved and then all the results are injected to the Init method.

It is also possible to manually specify which GameObjects should be searched for each argument. You can for example use the GetOrAddComponent value to try searching for the component in the same GameObject and then automatically adding it to it if no existing instance is found.

[InitInEditMode(From.Children, From.GetOrAddComponent, From.Scene)]
public class Player : MonoBehaviour<Collider, AnimatorController, Camera>

Initializer Support

It is also possible to add this attribute to an Initializer class.

From Initializer to Client

In this case, by default, the Init arguments will be taken from the Initializer, and passed to its client’s Init function. In other words, no arguments will be gathered from the scene or prefab hierarchy in this case, and no arguments will be passed to the Initializer.

From Hierarchy to Initializer & Client

If you specify from where arguments should be retrieved from, using any values other than From.Initializer, or From.Default, then the Init arguments will be located from theĀ  scene or prefab hierarchy, and passed to both the Initializer and its client.

Leave a Reply

Your email address will not be published. Required fields are marked *