PolygonCollider2D / Custom Inspector: "Edit Collider"-Button disappears when adding custom editor buttons.

I wrote a custom editor script to sort of “unify” the points of the collider i.e. if x- or y-values of multiple points in the collider’s path are similar (regarding a given tolerance), they are set to the same value.

The script itself works nicely as intended; but I have a problem with using it in the Unity-GUI: Whenever it is active, the “Edit Collider”-Button with the possibility to edit the collider’s path disappears:

With my script commented out:
[77953-script-off.jpg*_|77953]

With my script active:
[77954-script-on.jpg*_|77954]

I use the following code to add the buttons for BoxCollider2Ds:

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

[CustomEditor(typeof(PolygonCollider2D))]
public class PolygonColliderSmoother : Editor {
	private List<float> referencesX;
	private List<float> referencesY;

	public override void OnInspectorGUI() {
		base.OnInspectorGUI ();

		EditorGUILayout.BeginVertical ();

		if (GUILayout.Button ("Unify values with tolerance 0.5")) {
			Unify (0.5f);
		} else if (GUILayout.Button ("Unify values with tolerance 1")) {
			Unify (1);
		} else if (GUILayout.Button ("Unify values with tolerance 2")) {
			Unify (2);
		}
		EditorGUILayout.EndVertical(); 
	}


	private void Unify(float tolerance) {
		PolygonCollider2D collider = Selection.activeTransform.gameObject.GetComponent<PolygonCollider2D> ();
		Vector2[] path = collider.GetPath (0);
		Vector2[] newPath = new Vector2[path.Length];

		referencesX = new List<float> ();
		referencesY = new List<float> ();

		for(int i =0; i < path.Length; i++) {
			float useValueX, useValueY;
			Vector2 point = path *;*
  •  	int referenceIndexX = FindReferenceIndex (referencesX, point.x, tolerance);*
    
  •  	int referenceIndexY = FindReferenceIndex (referencesY, point.y, tolerance);*
    
  •  	if (referenceIndexX == -1) {*
    
  •  		referencesX.Add (point.x);*
    
  •  		useValueX = point.x;*
    
  •  	} else {*
    
  •  		useValueX = referencesX[referenceIndexX];*
    
  •  	}*
    
  •  	if (referenceIndexY == -1) {*
    
  •  		referencesY.Add (point.y);*
    
  •  		useValueY = point.y;*
    
  •  	} else {*
    
  •  		useValueY = referencesY[referenceIndexY];*
    
  •  	}*
    

_ newPath = new Vector2 (useValueX, useValueY);_
* }*

* collider.SetPath (0, newPath);*
* }*

* private int FindReferenceIndex(List list, float closeTo, float tolerance) {*
* return list.FindIndex(x => Mathf.Abs (x - closeTo) <= tolerance);*
* }*
}
Does anybody know what I am missing / should do here?
_*
_*

Hi @jwulf! The problem here is that the Edit Collider buttons are defined in an internal editor class (Specifically UnityEditor.ColliderEditorBase.InspectorEditButtonGUI()). When you create your own custom editor and assign it to the class with the CustomEditor attribute, your editor will be preferred, and the internal one will be ignored. So what you end up seeing is just the property fields and none of the other stuff defined in Unity’s internal custom editor.

I may soon be working on redesigning the Editor class a little bit to make this sort of thing easier, but the best option you have in the short term is to dig into the UnityEditor dll and either a) copy the parts of the code to replicate what you want or b) use reflection to get at the internal editor class and manage an instance of it inside your own editor. I’ve done both of these things in personal projects in the past, and while neither is ideal, they’re about the best choices you have for now.

You can use my code to modify the inspector, and override the function GetAssemblyEditorTypeName() to return “UnityEditor.PolygonCollider2DEditor”.
using UnityEditor;
using System;
using System.Reflection;
using Game;
using UnityEngine;

public abstract class NativeTypeEditor : Editor
{
    private string unityTypeName;
    private Editor editorInstance;
    private Type nativeEditor;
    private MethodInfo onSceneGUI;
    private MethodInfo onValidate;
    protected abstract string GetAssemblyEditorTypeName();
    protected virtual void Awake()
    {
        Initialize();
    }
    private void OnEnable()
    {
        Initialize();
        if (nativeEditor != null)
        {
            MethodInfo onEnable = nativeEditor.GetMethod("OnEnable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
            if (onEnable != null)
            {
                onEnable.Invoke(editorInstance, null);
            }
            onSceneGUI = nativeEditor.GetMethod("OnSceneGUI", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
            onValidate = nativeEditor.GetMethod("OnValidate", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
        }
    }
    private void OnDisable()
    {
        if (nativeEditor != null)
        {
            MethodInfo onDisable = nativeEditor.GetMethod("OnDisable", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
            if (onDisable != null)
            {
                onDisable.Invoke(editorInstance, null);
            }
        }
    }
    public override void OnInspectorGUI()
    {
        if (editorInstance != null)
        {
            editorInstance.OnInspectorGUI();
        }
    }
    private void OnSceneGUI()
    {
        if (onSceneGUI != null)
        {
            onSceneGUI.Invoke(editorInstance, null);
        }
    }
    
    private void OnValidate()
    {
        Initialize();
        if (nativeEditor != null)
        {
            MethodInfo onReset = nativeEditor.GetMethod("OnReset", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
            if (onReset != null)
            {
                onReset.Invoke(editorInstance, null);
            }
        }
    }
    
    private void OnDestroy()
    {
        if (nativeEditor != null)
        {
            MethodInfo onDestroy = nativeEditor.GetMethod("OnDestroy", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
            if (onDestroy != null)
            {
                onDestroy.Invoke(editorInstance, null);
            }
            DestroyImmediate(editorInstance);
            nativeEditor = null;
        }
    }
    private void Initialize()
    {
        if (unityTypeName == null)
        {
            unityTypeName = GetAssemblyEditorTypeName();
            if (unityTypeName.IsNullOrEmpty())
            {
                Debug.LogError("Error: You should override the function GetNativeTypeName and return the editor name in assembly");
                return;
            }
        }
        if (nativeEditor == null)
        {
            nativeEditor = Assembly.GetAssembly(typeof(Editor)).GetType(unityTypeName);
            if (nativeEditor == null)
            {
                Debug.LogError("Error: the return editor name of GetNativeTypeName is not correct. Samples: UnityEditor.RectTransformEditor");
                return;
            }
        }
        if (editorInstance == null)
        {
            editorInstance = CreateEditor(target, nativeEditor);
        }
    }
}