Need an architectural advice

Greetings!

I have a data flow shown here:

And I have a number of gamobjects on the scene. I want to edit(in Edit Mode/not play mode)each object individually. Each object has a component named ObjectDataHolder that is declared in a following way:

public class ObjectDataHolder : MonoBehaviour
{
    public ScriptableObject data;
}

The process of editting is this: I select object and click in context menu to edit it. Then a number of tools should be loaded into the current editor window(all stuff happens in editor window). The objects are different some are buildings, some are just static objects and others.

I want to show tools(within editor window) respective to the type of object I am editting at the moment. So the type of the object is the type of data. So if ObjectDataHolder.data type is BuildingData I want to show tools for buildings.

I could do the following:

ObjectDataHolder dataHolder = selectedGameObject.GetComponent<ObjectDataHolder>();
if (dataHolder.data is ProductiveBuildingData)
ShowToolsForProductiveBuildings();
else if (dataHolder.data is BonusBuildinData)
ShowToolsForBonusBuildingData();
else if ...

But this is not very convenient as when I add some more data types I would have to add code here as well.

Is here some better approach to use ?

Thank you in advance.

What about making ObjectDataHolder an interface with a generic parameter for the data type? As it’s a top level MonoBehaviour, having such a type hierarchy won’t be a problem with Unity’s serialization process.

Once you make each specific derivative class of the interface per each data type, it’d be easy to do the same for the editor part, using Unity’s builtin ability for matching a specific editor type for a component type.

Make an interface or a base class for all editable objects, and provide a virtual method “show tools” in it. Override in each object for different gui. If the method requires access to some data stored in an external object (say, some sort of SceneManager), pass that object as parameter.

Unless I’m mistaken, GetComponent also supports interfaces, so you could use those.

However… depending on what you’re doing you could simply ditch inheritance/polymorphism and write several custom editors for each class: Unity - Manual: Custom Editors

So, you’ll end up with the likes of:

[CustomEditor(typeof(BushData))]
class BushEditor: Editor{
....
}
[CustomEditor(typeof(BuildingData))]
class BuildingEditor: Editor{
....
}

etc.

The editors in turn could borrow each other’s functions or inherit from each other.