Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by jwulf · Sep 10, 2016 at 12:25 AM · inspectoreditor-scriptingcustom-inspectoreditorguilayoutpolygon collider 2d

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: alt text

With my script active: alt text

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 [i];
 
             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 [i] = new Vector2 (useValueX, useValueY);
         }
 
         collider.SetPath (0, newPath);
     }
 
     private int FindReferenceIndex(List<float> list, float closeTo, float tolerance) {
         return list.FindIndex(x => Mathf.Abs (x - closeTo) <= tolerance);
     } 
 }

Does anybody know what I am missing / should do here?

script-off.jpg (68.2 kB)
script-on.jpg (74.7 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Adam-Mechtley · Sep 12, 2016 at 06:47 AM

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.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jwulf · Sep 12, 2016 at 09:53 AM 0
Share

Hi @Adam-$$anonymous$$echtley, thanks a lot for the detailed explanation and suggestions! I think digging into the dll is a bit above my skill right now, but please allow me to ask a follow-up question with a different idea:

I tried moving my functionality to a custom window. So I created a window which checks if the current selection has a PolygonColider2D and if so, it shows the buttons just as described in my question above.

In that case, the "Edit Collider" button stays as desired in the inspector (of course, because I don't change the inspector at all), but when I push my custom buttons in the different window, it doesn't change the collider at all. I ensured via Debug.Log-Outputs that the function is indeed called, it just seems that collider.SetPath() is ignored. Is that because inspectors have some sort of higher priority and if other windows try to change a currently "inspected" elements, those changes are ignored or immediately overriden by the old values? Or am I possibly missing something else?

(Unfortunately, I can't post my code for that custom window because I am away from my workstation for a couple of days. But basically, I copied the code from above and used basic functionality as described in tutorials to create the window.)

avatar image Adam-Mechtley jwulf · Sep 12, 2016 at 11:23 AM 0
Share

@jwulf Nope I went ahead and did a quick test of my own and didn't see any problems. In the code you pasted above you are specifically getting/setting path 0. I'd maybe first check to make sure that's the right path index for the collider you're editing.

avatar image jwulf Adam-Mechtley · Sep 12, 2016 at 02:25 PM 0
Share

Cool, many thanks again for your effort! I'll try again in a couple of days when I have access to my project again.

avatar image
0

Answer by Rocksuit · Apr 17 at 07:15 AM

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);
         }
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

76 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Access an Array of class inside another Array of class? (EditorGUILayout) 1 Answer

Custom Inspector Script Resetting Information 0 Answers

Update object properties in editor 0 Answers

How do I use EditorGUILayout.EnumPopup with an enum with 'holes' in a custom inspector. 3 Answers

How to return the default value for EditorStyles.toolbarButton.normal.background ??? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges