RequireComponentOnRoot

Hello, I wrote this simple editor script to basically mimic Unity’s built-in RequireComponent attribute, but for the root object instead of the same object.

Is it possible to have the inspector say a warning that another object requires this component without creating custom inspector scripts for each new script that uses this attribute? Also, how can I detect if a component is being removed in the editor, like how a pop-up box appears when you try to remove a component that’s held on by Unity’s RequireComponent attribute? And, are there any other ways I can improve this?

using System;
using UnityEngine;

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class RequireComponentOnRootAttribute : Attribute
{
    /// <summary>
    /// The type of component to be required on the root gameobject.
    /// </summary>
    public Type type;
    /// <summary>
    /// Whether or not only one instance of the required component is allowed in the entire transform hierarchy.
    /// </summary>
    public bool singleton = false;

    public RequireComponentOnRootAttribute(Type type)
    {
        if (!(type.IsSubclassOf(typeof(Component)) || type == typeof(Component)))
        {
            throw new ArgumentException("type must derive from Component or MonoBehaviour.", "type");
        }
        this.type = type;
    }
}
using System;
using UnityEditor;
using UnityEngine;

[InitializeOnLoad]
public class RequireComponentOnRootExecution
{
    static RequireComponentOnRootExecution()
    {
        EditorApplication.delayCall += Update;
        EditorApplication.hierarchyWindowChanged += Update;
        EditorApplication.projectWindowChanged += Update;
    }

    static void Update()
    {
        foreach (var comp in UnityEngine.Object.FindObjectsOfType<Component>())
        {
            RequireComponentOnRootAttribute attribute = (RequireComponentOnRootAttribute) Attribute.GetCustomAttribute(comp.GetType(), typeof(RequireComponentOnRootAttribute));
            if (attribute != null)
            {
                Transform root = comp.transform.root;

                if (root.GetComponent(attribute.type) == null)
                {
                    Debug.LogWarning(comp.GetType() + " requires the root gameobject to contain " + attribute.type + ". Adding to '" + root.name + "'...");
                    root.gameObject.AddComponent(attribute.type);
                }
                if (attribute.singleton)
                {
                    var arr = root.GetComponentsInChildren(attribute.type);
                    for (int i = 1; i < arr.Length; i++)
                    {
                        Debug.LogWarning(comp.GetType() + " only allows one " + attribute.type + " in its transform hierarchy. Removing " + attribute.type + " from '" + arr[i].name + "'...");
                        UnityEngine.Object.DestroyImmediate(arr[i]);
                    }
                }
            }
        }
    }
}

kkk