Get Editor-Script from Runtime-Script

Hi, I have a dilemma that I never knew how to solve:

I want to access the corresponding Editor-Script from my Runtime-Script (target).
This is how it looks like now:

public class MyClass : MonoBehaviour, IFeatureInterface {
  public void DoStuff() {
    [ ... ]
    HelperClass.DoInelligentStuff();
    [ ... ]
  }
}
public static class HelperClass {
  public static void DoInelligentStuff() {
    if (Application.isPlaying) {
      UnityEngine.Function();
    }
#if UNITY_EDITOR
    else {
      UnityEditor.Function();
    }
#endif
  }
}

As you can see, I have to use a different functionality inside the editor, which utilizes functions from the UnityEditor namespace in the real code. This is because I can’t use the runtime code inside the DoStuff() when in edit mode. The editor functionality is programmed by me and makes the runtime code work for us inside the editor.
In an extra Editor-Window I just search for all instances in the scene with the IFeatureInterface and then call DoStuf() on them.
But now, since the project grew and I’m trying to implement Assembly Definitions, I will now have to separate the code, there is no #if UNITY_EDITOR hack possible anymore. But all possibilities that come to mind won’t work one way or the other.

I thought about adding an Editor-Script to MyClass, which implements an editor version of DoStuff() which then does the editor functionality instead of the current helper class doing it. But I can’t catch the function call in the editor script, it doesn’t know when DoStuff() is called inside the runtime script.

Another option would be to search all IFeatureInterface an then don’t get MyClass, but the corresponding MyClassEditor script. I know I can get the runtime class with the “target” variable, but the other way around is not possible as far as I know. However this leads to a ton of duplicated code, that needs to be implemented on any class that implements the IFeatureInterface…

It would still be great if the helper class would be able to solve this, because I would have to write a ton of duplicate code, but the two option above seem like the only possibilities, even if they suck in this case…

How would one overcome this dilemma? I really need to get this fixed, hope you have some cool suggestions on how to do this :wink:

I really need some suggestions on this one, the problem is quite easy to understand. I took the effort to draw a schematic on what’s going on for you, in the hopes that someone will take the time to understand my struggle:


The main issue is, that the HelperClass can’t have the #if UNITY_EDITOR tag anymore, because of the .asmdef splitting.
So one Idea was to move the functionality into every IFeatureInterface implementations Editor Scripts (MyClass1Editor, MyClass2Editor, …). Which would mean a shit ton of duplicated code, since the whole functionality of the DoStuff() function would have to be duplicated. The only difference inside the editor is just this one little line HelperClass.DoIntelligentStuff() that makes it work inside edit mode. This code as you can see, is moved into my static HelperClass.

Even if I would say – okay, this is my last resort – let’s move a duplicate of DoStuff() inside every editor class and change this one line. I’ll have the issue, that MyEditorWindow is not able to get the editor scripts from the runtime classes and trigger the editor version of DoStuff(). I can search for all MonoBehaviours that implement IFeatureInterface no problem, but getting their corresponding editor scripts seems impossible.

Any other solution is appreciated. The way it works right now (seen above) is pretty awesome, since the runtime scripts don’t care, they all call the same function, if Unity is in edit mode, only the helper class will act differently. The code variance is contained within this single script.

But this “hack” must be cleanly separated to be able to precompile as a .dll.

To be honest, I didn’t read/understand your explanation completely…

But would using Application.isEditor instead of #define directives be enough?

So something like:

public static class HelperClass
{
    public static void DoIntelligentStuff()
    {
        if (Application.isPlaying)
        {
            Debug.Log("Runtime Functionality");
        }
        else if (Application.isEditor)
        {
            Debug.Log("Editor Functionality");
        }
    }
}

Good point, I didn’t make that clear, the placeholder Debug.Log("Editor Functionality") includes Editor namespace functions in the real code, so it needs to be excluded, otherwise the Script wouldn’t compile in a build.
I will change that in my original question!

1 Like