[SOLVED] CustomEditor - Awake calling repeatedly - Looking for init method

Hello! I found probably bug in Unity 5.6.0f3, I created script which extends Editor and only has attribute CustomEditor.
This CustomEditor is targeted to MeshRenderer.

I need method which will be called only once! (aka initialization)
In Unity life cycle is Awake called once. (OnEnable is called everytime when is script enabled)
I know about that so Awake is called everytime when object is selected. It is OK but it cannot be called xxx times!

Code

//Fields here...
private void Awake(){
        renderer = (Renderer) target;

        if (renderer.sharedMaterial == null)
            return;

        if (material == null) {
            originalMaterial = renderer.sharedMaterial;
            material = new Material(renderer.sharedMaterial);
            renderer.sharedMaterial = material;
            //material.name = originalMaterial.name + " (Unlinked)";
            Debug.Log("Material is null : " + originalMaterial.name);
        }
}

When I go to editor now and select object where is my CustomEditor interface.
Then in Console you can see:

It is called 539+ times.

I’m not using only Awake method, also using OnInspectorGUI()
Where I calls

  • serializationObject.Update();
  • UI Elements
  • serializedObject.ApplyModifiedProperties();

I’m not calling nothing as repaint, events, etc…

Any ideas?

// Update 1
When I disable script via checkbox, Awake is always calling. When I disable gameobject, Awake is still calling. Something is totally wrong.

create a bool

//Fields here...

private bool awakeHasRan = false;

private void Awake(){
        renderer = (Renderer) target;
 
        if (renderer.sharedMaterial == null)
            return;
 
        if (material == null && awakeHasRan == false) {
            awakeHasRan = true;
            originalMaterial = renderer.sharedMaterial;
            material = new Material(renderer.sharedMaterial);
            renderer.sharedMaterial = material;
            //material.name = originalMaterial.name + " (Unlinked)";
            Debug.Log("Material is null : " + originalMaterial.name);
        }
}

That will not work. Because script is everytime destroyed when object is deselected and created when object is selected.
And Singleton is not that what I want.

Persisting editor data is horrible. We usually go with caching stuff statically, since Unity destroys all Editor objects.

In your case, that would be something like:

private static HashSet<MeshRenderer> hasBeenInitialized;

private void Awake() {
    var mr = (MeshRenderer) target;
    if (!hasBeenInitialized.Contains(mr)) {
        InitializeMR(mr);
        hasBeenInitialized.Add(mr);
    }
}

EDIT: by the way, I have no idea what the difference between using Awake and OnEnable for Editors are, since they seem to always be destroyed when you deselect them, so both always gets called.

Thanks for answer. This looks as only way to fix it.

Awake is called less time than OnEnable. (That would be better for this check)