Search Unity

Is it possible to toggle the "Edit Collider" mode of a Polygon Collider 2D via script?

Discussion in 'Scripting' started by Tom980, Aug 23, 2018.

  1. Tom980

    Tom980

    Joined:
    Mar 5, 2017
    Posts:
    9
    Short description: I wanna write a script and when I'm clicking onto a GameObject in the scene or the Hierarchy that has this script attatched it should instantly trigger this object's Polygon Collider to go into edit mode without me pressing that button: *- Screenshot (7).png -*

    Now I already built up the script's structure so that it is [ExecuteInEditMode] but the Update portion only compiles for the Unity Editor and only runs when I'm not in playmode, the only thing I need to complete this nice little tool to help me design my game is a reference to this "Edit Collider" button.

    Can I actually access the edit mode of a Polygon Collider 2D via some kind of script method or variable (like getComponent<PolygonCollider2D>.toggleEditMode() or .setEditMode for example)?

    And I know this is a very uncommon desire but let me explain myself first:
    I'm using a collection of scripts from ViicEsquivel and pakfront that are taking the shape of a Polygon Collider 2D and convert it into a 2D Mesh, basically making the collider visible and renderable at runtime (the scripts can be found here https://answers.unity.com/questions/835675/how-to-fill-polygon-collider-with-a-solid-color.html). This is so convenient that I decided to make nearly the entire static part (a.k.a. walls) of the world geometry for my 2D space game just by shaping Polygon Collider verticies and applying those scripts.
    But needing to press the Edit Collider button everytime I want to shape a wall will most likely slow down my workflow by a lot which is why I want to write a script to do it for me. I just can't find a way to pull this one off myself /:
     

    Attached Files:

  2. infosekr

    infosekr

    Joined:
    Jul 12, 2013
    Posts:
    46
    I'm also using a similar work flow. Did you find a way to access the button, maybe using reflection?
     
  3. infosekr

    infosekr

    Joined:
    Jul 12, 2013
    Posts:
    46
    I figured out how to do this with reflection against Unity 2018.2.21. Here's some snippets from the code I used on my editor window tool. No guarantees it will work on different versions of Unity though.

    Code (CSharp):
    1. private object m_polygonUtility = null;
    2. private MethodInfo m_polygonUtilityStartEditing = null;
    3. private MethodInfo m_polygonUtilityStopEditing = null;
    4. private MethodInfo m_polygonUtilityOnSceneGUI = null;
    5.  
    6. public void editPolygon(GameObject obj)
    7. {
    8.     if (m_polygonUtility == null)
    9.     {
    10.         System.Type type = Assembly.LoadWithPartialName("UnityEditor").GetType("UnityEditor.PolygonEditorUtility");
    11.         var ctors = type.GetConstructors();
    12.         m_polygonUtility = ctors[0].Invoke(new object[] { });
    13.         m_polygonUtilityStartEditing = type.GetMethod("StartEditing");
    14.         m_polygonUtilityStopEditing = type.GetMethod("StopEditing");
    15.         m_polygonUtilityOnSceneGUI = type.GetMethod("OnSceneGUI");
    16.     }
    17.  
    18.     PolygonCollider2D collider = obj.GetComponent<PolygonCollider2D>();
    19.     if (collider != null)
    20.     {
    21.         m_polygonUtilityStartEditing.Invoke(m_polygonUtility, new object[] { collider });
    22.     }
    23. }
    24.  
    25. void OnSceneGUI(SceneView sceneView)
    26. {
    27.     if (m_polygonUtilityOnSceneGUI != null)
    28.     {
    29.         m_polygonUtilityOnSceneGUI.Invoke(m_polygonUtility, new object[] { });
    30.     }
    31. }
     
    _geo__ likes this.
  4. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    1,343
    Thanks for this, still works in Unity 2019.4.x!

    I have taken the liberty to make it into a static class for easier use. I've also added some workarounds for cases in which UnityEditor might crash (still does sometimes, so use with care!). Hope others will find it useful.

    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using System;
    3. using System.Reflection;
    4. using UnityEditor;
    5. using UnityEngine;
    6.  
    7. namespace yourCoolNamespace
    8. {
    9.     /// <summary>
    10.     /// Enables to start and stop editing a PolygonCollider2D via script.
    11.     /// Based on "infosekr"s code, see: https://forum.unity.com/threads/is-it-possible-to-toggle-the-edit-collider-mode-of-a-polygon-collider-2d-via-script.546561/
    12.     ///
    13.     /// Usage:
    14.     ///     EditPolygonCollider2D.Start( aGameObjectWithAColliderOnIt );
    15.     ///     EditPolygonCollider2D.Stop( aGameObjectWithAColliderOnIt );
    16.     ///
    17.     /// Settings:
    18.     ///     EditPolygonCollider2D.DisableColliderWhileEditing (bool, default true).
    19.     ///       This was necessary because Unity tends to crash if edit is started via this
    20.     ///       script but not ended via script. To avoid this we simpy disable editing on
    21.     ///       the collider while we edit via script.
    22.     /// </summary>
    23.     [InitializeOnLoad]
    24.     public static class EditPolygonCollider2D
    25.     {
    26.         public static bool DisableColliderWhileEditing = true;
    27.  
    28.         static object polygonUtility = null;
    29.         static MethodInfo polygonUtilityStartEditing = null;
    30.         static MethodInfo polygonUtilityStopEditing = null;
    31.         static MethodInfo polygonUtilityOnSceneGUI = null;
    32.         static bool onListenerActive = false;
    33.         static GameObject currentlyEditedObject;
    34.         static HideFlags currentlyEditedObjectHideFlags;
    35.  
    36.         static EditPolygonCollider2D()
    37.         {
    38.             cacheTypeInfosIfNecessary();
    39.         }
    40.  
    41.         static void cacheTypeInfosIfNecessary()
    42.         {
    43.             if (polygonUtility == null)
    44.             {
    45.                 System.Type type = Assembly.Load("UnityEditor").GetType("UnityEditor.PolygonEditorUtility");
    46.                 var ctors = type.GetConstructors();
    47.                 polygonUtility = ctors[0].Invoke(new object[] { });
    48.                 polygonUtilityStartEditing = type.GetMethod("StartEditing");
    49.                 polygonUtilityStopEditing = type.GetMethod("StopEditing");
    50.                 polygonUtilityOnSceneGUI = type.GetMethod("OnSceneGUI");
    51.             }
    52.         }
    53.  
    54.         static void setListeners( bool active )
    55.         {
    56.             if (active)
    57.             {
    58.                 if (onListenerActive == false)
    59.                 {
    60. #if UNITY_2019_1_OR_NEWER
    61.                     SceneView.duringSceneGui += OnSceneGUI;
    62. #else
    63.                     SceneView.onSceneGUIDelegate += OnSceneGUI;
    64. #endif
    65.                     Selection.selectionChanged += OnSelectionChanged;
    66.                 }
    67.             }
    68.             else
    69.             {
    70.                 if (onListenerActive == true)
    71.                 {
    72. #if UNITY_2019_1_OR_NEWER
    73.                     SceneView.duringSceneGui -= OnSceneGUI;
    74. #else
    75.                     SceneView.onSceneGUIDelegate -= OnSceneGUI;
    76. #endif
    77.                     Selection.selectionChanged -= OnSelectionChanged;
    78.                 }
    79.             }
    80.             onListenerActive = active;
    81.         }
    82.  
    83.         private static void OnSelectionChanged()
    84.         {
    85.             if(currentlyEditedObject != null && Selection.activeGameObject != currentlyEditedObject)
    86.             {
    87.                 Stop(currentlyEditedObject.transform);
    88.             }
    89.         }
    90.  
    91.         public static void Start(Component obj)
    92.         {
    93.             Start(obj.transform);
    94.         }
    95.  
    96.         public static void Start(GameObject obj)
    97.         {
    98.             Start(obj.transform);
    99.         }
    100.  
    101.         public static void Start(Transform trans)
    102.         {
    103.             Tools.current = Tool.None;
    104.             currentlyEditedObject = trans.gameObject;
    105.             cacheTypeInfosIfNecessary();
    106.             PolygonCollider2D collider = trans.GetComponent<PolygonCollider2D>();
    107.             if (collider != null)
    108.             {
    109.                 polygonUtilityStartEditing.Invoke(polygonUtility, new object[] { collider });
    110.                 setListeners(true);
    111.             }
    112.  
    113.             if(DisableColliderWhileEditing)
    114.             {
    115.                 currentlyEditedObjectHideFlags = collider.hideFlags;
    116.                 collider.hideFlags = HideFlags.NotEditable;
    117.             }
    118.         }
    119.  
    120.         public static void Stop(Component obj)
    121.         {
    122.             Stop(obj.transform);
    123.         }
    124.  
    125.         public static void Stop(GameObject obj)
    126.         {
    127.             Stop(obj.transform);
    128.         }
    129.  
    130.         public static void Stop(Transform trans)
    131.         {
    132.             currentlyEditedObject = null;
    133.             cacheTypeInfosIfNecessary();
    134.             PolygonCollider2D collider = trans.GetComponent<PolygonCollider2D>();
    135.             if (collider != null)
    136.             {
    137.                 polygonUtilityStopEditing.Invoke(polygonUtility, new object[] {});
    138.                 setListeners(false);
    139.             }
    140.  
    141.             if (DisableColliderWhileEditing)
    142.             {
    143.                 collider.hideFlags = currentlyEditedObjectHideFlags;
    144.             }
    145.         }
    146.  
    147.         public static void OnSceneGUI(SceneView sceneView)
    148.         {
    149.             if (polygonUtilityOnSceneGUI != null)
    150.             {
    151.                 polygonUtilityOnSceneGUI.Invoke(polygonUtility, new object[] { });
    152.             }
    153.         }
    154.     }
    155. }
    156.  
    157. #endif
     
    Last edited: Jul 20, 2020
    oprel likes this.
  5. safacon

    safacon

    Joined:
    Sep 5, 2013
    Posts:
    5
    This is what I found (needs the Game Object selected)
    Code (CSharp):
    1. ToolManager.SetActiveTool(Assembly.Load("UnityEditor").GetType("UnityEditor.PolygonCollider2DTool"));