Here's a cheeky workaround you can use.
First we define an empty struct, so it doesn't actually increase the memory allocation of our components:
[System.Serializable]
public struct NamespaceHint
{
}
Then we give it a PropertyDrawer
(placed in a folder called "Editor") that prints out the fully-qualified name of the component it's attached to:
[CustomPropertyDrawer(typeof(NamespaceHint))]
public class NamespaceHintDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var t = property.serializedObject.targetObject.GetType();
EditorGUI.LabelField(position, t.FullName);
}
}
Then for any type that's ambiguous, we can add a little hint at the top of the inspector:
namespace Player
{
public class Controller : MonoBehaviour
{
[SerializeField] NamespaceHint _ns;
// ... other members...
}
}
And now two identical components in different namespaces are distinguishable in the Inspector - though you still have to guess and check when selecting them from the Add Component menu:
You could also do this manually with a [Header("Player.Controller")]
attribute if you don't need it to automatically adapt to name changes.
But note how much better this looks if we just give classes unique names to begin with:
Boom. We can tell them apart in the component selection menu and we don't need this boilerplate at the top of the script, so it's even less to type!