1
\$\begingroup\$

It's always a good idea to separate code sections with namespaces and based on that you can have many classes with the same name.

The problem is that in Unity when you want to add a class as a component or somewhere else, it doesn't show namespace info. So probably devs make mistakes.

Is there a way around it or some editor extensions?

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I'd challenge the "always a good idea...you can have many classes with the same name" — I think re-using a name, even with namespaces, is unnecessarily confusing. I've never had a situation in any single game project where I needed two different types to have the same name. \$\endgroup\$
    – DMGregory
    Commented Oct 20, 2022 at 12:56
  • \$\begingroup\$ @DMGregory namespaces help more cohesion on your code that solves a certain problem and more readability. in a team or big team, many repeating things happen and the namespace tells that the class is for a certain part of the game. with namespaces, repeating class names happen. \$\endgroup\$
    – virtouso
    Commented Oct 20, 2022 at 13:09
  • 1
    \$\begingroup\$ I don't think it works when searching but otherwise isn't [AddComponentMenu("folder/name")] attribute intended for that. \$\endgroup\$
    – Nikaas
    Commented Oct 21, 2022 at 8:15

1 Answer 1

4
\$\begingroup\$

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.

You could also do this manually with a [Header("Player.Controller")] attribute if you don't need it to automatically adapt to name changes.

Unfortunately, you still have to guess and check when selecting them from the Add Component menu:

Two controller components, one labelled "Enemy.Controller", one "Player.Controller"

To fix that, you can add an AddComponentMenu attribute to the top of your class to change its label/sorting in the add component menu:

[AddComponentMenu("Scripts/Player Controller")]
public class Controller : MonoBehaviour {
// ...

Add Component menu with unique component names

...but that one would need manual updates if you change your naming scheme.


But note how much better this looks and how much easier we can get it if we just give classes unique names to begin with:

namespace Player {
    public class PlayerController : MonoBehaviour {
    // ...

Same example, but with classes named EnemyController and PlayerController

Boom. We can tell them apart in the inspector and component selection menu, and we don't need any extra boilerplate at the top of the script, so it's even less to type! The only downside is a slightly longer component name / more redundant-looking fully qualified name to reference in scripts: Player.PlayerController.

\$\endgroup\$
1
  • \$\begingroup\$ great job. I think its the best I can get at the moment. \$\endgroup\$
    – virtouso
    Commented Oct 20, 2022 at 14:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .