Run code on "Add Component"

I would like to write some code that will automatically set up particular components the way i like them set up when someone adds that component from the “Add Component” button at the bottom of the inspector. I already have my code as a menu item however would prefer this method as well.

Can anyone suggest anything?

You can probably use Unity - Scripting API: ExecuteInEditMode along with checking if (Application.isEditor && !Application.isPlaying), unless it should be run in play mode too.

I need this on the editor side not on the non-editor side.

I have no idea if this would work, but you could try making a custom constructor for your class, and in it look for the components you want to set. If they exist, than GetComponent<>() and do what you gotta do

that would most likely work non-editor side. however i need something editor side

This is exactly what you want. Execute in edit mode will run code in Edit Mode (i.e. in the Editor). Then you would check if you are in the editor, and the game is not playing (i.e. edit-mode), then run whatever code you want.

Alternatively, you can make use of the Reset function, which is called whenever you Add a component in the editor, or choose to Reset it (https://docs.unity3d.com/ScriptReference/MonoBehaviour.Reset.html)

3 Likes

No that is not what i want. i do not want my script executing in edit mode. i want a function that is in a CS file in the editor folder to be called when someone clicks on my classes name in the “Add Component” list. then i will be able to do things only available in editor mode to setup my assets the way i prefer

The reset looks like it could work. However it requires me to have editor code in my classes’ CS file.

You could overwrite the AddComponentMenu menu option and do the stuff you what to do that way.

again i need this to be on the editor side. therefore attaching more stuff to the Monobehavior is nice. it does not allow me to get to certain things inside the UnityEditor namespace without numerous #if UNITY_EDITOR across my code. if that is the way that Unity designed it and it can not be worked around, then that is understandable i will work with unclean code.however the editor folders are designed for unity editor specific things of which this should be one. why can i not access this through code only available in the editor folders?

You can hide the normal add component entry via the AddComponentMenu
atribute.

Then you can use a editor script that lives inside the editor folder to create a menu entrance for attaching the component.

(inside the editor script)

    [MenuItem("Component/Scripts/DisableOnStart")]
    static void DisableOnStartConstructor(MenuCommand command)
    {
        Debug.Log("Do stuff");
        Selection.activeGameObject.AddComponent<DisableOnStart>();
    }

For that you can use the “MenuItem” Atribute

Its not the same as the original addcomponent entry but for strict separation of editor and runtime code this should work.

the “” does remove the component from the menu. however since i cant remove standard unity items i guess the best thing to do would to be drop this as there are ways apparently to do it however nothing that is entirely clean.

You can just wrap the entire Reset function within #if UNITY_EDITOR.

If you want the script to be called to live in the Editor folder instead of in the MonoBehaviour, then you could create a custom inspector for the MonoBehaviour in the Editor folder, and take advantage of that.

Is there something you dislike about compiler #if defines? They don’t instantly mean unclean code - they are essential for cross-platform development in many cases, and make things much simpler and easier to follow than some alternatives.

2 Likes

sorry for the necro but i think this wil help futur seekers , i found a solution and i wanted to share it , you can subscribe to this (Unity - Scripting API: ObjectFactory.componentWasAdded) event in the editor.
Here’s an example where i use it to disable Raycast/Masking on added UI components

    [InitializeOnLoad]
    public class EditorOnComponentAdded
    {
        static EditorOnComponentAdded()
        {
            ObjectFactory.componentWasAdded -= HandleComponentAdded;
            ObjectFactory.componentWasAdded += HandleComponentAdded;

            EditorApplication.quitting -= OnEditorQuiting;
            EditorApplication.quitting += OnEditorQuiting;
        }
        private static void HandleComponentAdded(UnityEngine.Component obj)
        {
            if (obj is Graphic graphic)
            {
                graphic.raycastTarget = false;
            }
            if (obj is MaskableGraphic maskable)
            {
                maskable.maskable = false;
            }
        }

        private static void OnEditorQuiting()
        {
            ObjectFactory.componentWasAdded -= HandleComponentAdded;
            EditorApplication.quitting -= OnEditorQuiting;
        }
    }
14 Likes