Editor performance drop - FlushDirty?

Hi, I am currently in the process of making my own Editor script, but for some reason I am getting huge performance drop when manipulating a simple Range slider on a GameObject which have an editor script associated.

Ignore the performance drop in “DockArea.OnGUI()” as this is caused by the profiler itself.

I can’t seem to find any information on FlushDirty. My best lead is that it has something to do with some changes occuring after Unity 5.3: Unity - Scripting API: EditorUtility.SetDirty. I am using Unity 5.3.5f1. If anyone could enlighten me on what FlushDirty is, that would be much appreciated.

What was your slider doing? Flush is usually used when the cpu is sleeping. It forces the queued commands to the GPU.

Unity use could be different, the link you sent is to set dirty which is used when a object is modified by an editor script. Maybe the changes your doing to the object are put in a queue then are flushed to save?

Alright, I’ll try to explain it.

Currently the slider does absolutely nothing. I use a [Range(x,x)] tag, on a float variable in a non-Monobehaviour serializable object class, lets call it “Enemy class”. Another Monobehaviour class, lets call it “Path Class” is using the Enemy class as a field. The custom editor class is associated with the Path class and makes use of OnScreenGUI callback to create and draw a bunch lines (I am using the Velosity plugin). After the lines have been created, the lines will not be updated again until a transform has been manipulated.

The strange part is, if I comment out the section that draws the line, manipulating the slider created no hiccups. If the lines are created only once, manipulating the sliders creates huge performance drops in the editor (up to 400-600ms hiccups).

Pseudo code of my situation: Take note that “distance” is not used for anything, but if the slider is manipulated the hiccups are present.

[System.Serializable]
public class EnemySettings
{
    [Range(0, 1)]
    public float distance;
}

public class PathChunk : MonoBehaviour
{
    EnemySettings[] enemies;
    PathLines meshFilterPaths;
}

[CustomEditor(typeof(PathChunk))]
public class PathChunkEditor : Editor
{
    void OnSceneGUI()
    {
        PathChunk path = (PathChunk)target;

        //Create Unity Handles to manipulate lines
        Handles.DrawCoolHandles();

        //Create meshFilters that represents lines, but only once. Update if hasTransformChanged is true.
        path.meshFilterPaths = GeneratePathOnlyOnce(hasTransformChanged);
    }
}

– Update –
I have found out the following:

I have a prefab that got a PathChunk script attached. In the project, it is empty like this:

The second I add it to the scene. The “Lines” array is populated only once. This is done only once inside the OnScreenGUI and safeguards are placed so when a transform has been modified the Lines array is updated.


I expanded one of the Lines just to show you that each Lines contains a good portion of information ranging from vertices to UV coordinates.

The strange thing is, the second I add another EnemySettings, both EnemySettings and the “Lines” becomes marked as dirty.

And so does each element in the Lines array:

From this point, each manipulation inside the “PathChunk” component creates huge spikes, which appears to come from “FlushDirty”. If I apply the prefab, the performance spikes are fixed and I can continue working as usual. Anybody knows what is causing this behaviour?

I haven’t really found a fix for this yet. The best solution I have come up with so far, is simply to remove serialization of Lines.

Problem is reoccurring. Still looking for a solution.

You helped my find a solution!! Basically, I just apply the prefab in Code after any manipulation that changes the data. Turned a 100sec operation for me into 100ms :slight_smile:

if (UnityEditor.PrefabUtility.GetPrefabType(this.gameObject) == UnityEditor.PrefabType.PrefabInstance
            || UnityEditor.PrefabUtility.GetPrefabType(this.gameObject) == UnityEditor.PrefabType.DisconnectedPrefabInstance)
{
    Object prefabParent = UnityEditor.PrefabUtility.GetPrefabParent(this.gameObject);
    Debug.AssertFormat(UnityEditor.PrefabUtility.GetPrefabType(prefabParent) == UnityEditor.PrefabType.Prefab, prefabParent, "Expexcted {0} to be a prefab?", prefabParent.name);
    UnityEditor.PrefabUtility.ReplacePrefab(this.gameObject, prefabParent, UnityEditor.ReplacePrefabOptions.ConnectToPrefab);
}
1 Like