PolyLineEditor

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(Created page with "==Description== Here is a an exemple of how to use the Unity Handles class and adding custom editing tools. Image:Exemple_Polyline.jpg‎ This tool adds "inScene" controls...")
 
(C#)
Line 14: Line 14:
 
=== C# ===
 
=== C# ===
 
<csharp>
 
<csharp>
 +
 
using UnityEditor;
 
using UnityEditor;
 
using UnityEngine;
 
using UnityEngine;
 
using System.Collections;
 
using System.Collections;
 +
using System;
 +
using System.Reflection;
 +
 +
// Thanks to Dantus from EddelWeiss Interactive for this trick
 +
public class DefaultHandles
 +
{
 +
    public static bool Hidden
 +
    {
 +
        get
 +
        {
 +
            Type type = typeof(Tools);
 +
            FieldInfo field = type.GetField("s_Hidden", BindingFlags.NonPublic | BindingFlags.Static);
 +
            return ((bool)field.GetValue(null));
 +
        }
 +
        set
 +
        {
 +
            Type type = typeof(Tools);
 +
            FieldInfo field = type.GetField("s_Hidden", BindingFlags.NonPublic | BindingFlags.Static);
 +
            field.SetValue(null, value);
 +
        }
 +
    }
 +
}
  
 
[CustomEditor(typeof(PolyLine))]
 
[CustomEditor(typeof(PolyLine))]
Line 24: Line 47:
 
   // Event current;
 
   // Event current;
  
     int index = -1;
+
     int curPointIndex = -1;
 +
    bool hideDefaultHandle = true;
  
      
+
     void OnEnable()
 +
    {
 +
        DefaultHandles.Hidden = hideDefaultHandle;
 +
    }
  
     void Start()
+
     void OnDisable()
 
     {
 
     {
     
+
        DefaultHandles.Hidden = false;
 
     }
 
     }
  
Line 89: Line 116:
 
     void insideSceneGUI(PolyLine polyLine)
 
     void insideSceneGUI(PolyLine polyLine)
 
     {
 
     {
         Rect size = new Rect(0, 0, 300, 250);
+
         Rect size = new Rect(0, 0, 300, 200);
         float sizeButton = 40;
+
         float sizeButton = 30;
 
         Handles.BeginGUI();
 
         Handles.BeginGUI();
 
       //  Handles.BeginGUI(new Rect(Screen.width - size.width - 10, Screen.height - size.height - 10, size.width, size.height));
 
       //  Handles.BeginGUI(new Rect(Screen.width - size.width - 10, Screen.height - size.height - 10, size.width, size.height));
Line 102: Line 129:
 
         GUI.Label(rc, "Double Clic on Circles to select a point");
 
         GUI.Label(rc, "Double Clic on Circles to select a point");
 
         rc.y += sizeButton;
 
         rc.y += sizeButton;
         if (index != -1)
+
         if (curPointIndex != -1)
 
         {
 
         {
             GUI.Label(rc, "Current Point " + index);
+
             GUI.Label(rc, "Current Point " + curPointIndex);
 
             rc.y += sizeButton;
 
             rc.y += sizeButton;
  
Line 112: Line 139:
 
             if (GUI.Button(rc, "Insert Before"))
 
             if (GUI.Button(rc, "Insert Before"))
 
             {
 
             {
                 insert(polyLine, index);
+
                 insert(polyLine, curPointIndex);
 
             }
 
             }
 
             rc.x += rc.width;
 
             rc.x += rc.width;
 
             if (GUI.Button(rc, "Delete"))
 
             if (GUI.Button(rc, "Delete"))
 
             {
 
             {
                 Delete(polyLine, index);
+
                 Delete(polyLine, curPointIndex);
 
             }
 
             }
 
             rc.x += rc.width;
 
             rc.x += rc.width;
 
             if (GUI.Button(rc, "Insert After"))
 
             if (GUI.Button(rc, "Insert After"))
 
             {
 
             {
                 insert(polyLine, index + 1);
+
                 insert(polyLine, curPointIndex + 1);
                 index++;
+
                 curPointIndex++;
 
             }
 
             }
  
Line 145: Line 172:
 
                 {
 
                 {
 
                     insert(polyLine, 0);
 
                     insert(polyLine, 0);
                     index = 0;
+
                     curPointIndex = 0;
 
                 }
 
                 }
 
                 rc.x += rc.width;
 
                 rc.x += rc.width;
Line 151: Line 178:
 
                 {
 
                 {
 
                     insert(polyLine, -1);
 
                     insert(polyLine, -1);
                     index = polyLine.positions.Length - 1;
+
                     curPointIndex = polyLine.positions.Length - 1;
 
                 }
 
                 }
 
                 rc.y += sizeButton;
 
                 rc.y += sizeButton;
Line 162: Line 189:
 
             rc.width = size.width / 2;
 
             rc.width = size.width / 2;
 
             rc.x = 0;
 
             rc.x = 0;
             rc.y += 2*sizeButton;
+
             rc.y += sizeButton+10;
 
             if (GUI.Button(rc, "Clear All"))
 
             if (GUI.Button(rc, "Clear All"))
 
             {
 
             {
 
                 polyLine.positions = new Vector3[0];
 
                 polyLine.positions = new Vector3[0];
                 index = -1;
+
                 curPointIndex = -1;
 
             }
 
             }
 
             rc.x += rc.width;
 
             rc.x += rc.width;
Line 175: Line 202:
 
                     polyLine.positions[i].y = 0;
 
                     polyLine.positions[i].y = 0;
 
                 }
 
                 }
 +
            }
 +
        }
 +
 +
        rc.y += sizeButton + 10;
 +
        rc.x = 0;
 +
        rc.width = size.width;
 +
        if (hideDefaultHandle)
 +
        {
 +
            if (GUI.Button(rc, "Show Main Transform"))
 +
            {
 +
                hideDefaultHandle = false;
 +
                DefaultHandles.Hidden = hideDefaultHandle;
 +
            }
 +
        }
 +
        else
 +
        {
 +
            if (GUI.Button(rc, "Hide Main Transform"))
 +
            {
 +
                hideDefaultHandle = true;
 +
                DefaultHandles.Hidden = hideDefaultHandle;
 
             }
 
             }
 
         }
 
         }
Line 184: Line 231:
 
     void OnSceneGUI ()  
 
     void OnSceneGUI ()  
 
     {
 
     {
         //current = Event.current;
+
         // Thank to Dantus from Edelweiss for this helper
 
+
       
+
 
         // You need them somewhere.
 
         // You need them somewhere.
 
         Quaternion handleRotation = Quaternion.identity;
 
         Quaternion handleRotation = Quaternion.identity;
Line 212: Line 257:
  
 
             Handles.ScaleValueHandle(0, pos, Quaternion.identity, size, Handles.SphereCap, 0);
 
             Handles.ScaleValueHandle(0, pos, Quaternion.identity, size, Handles.SphereCap, 0);
             if (index == i)
+
             if (curPointIndex == i)
 
             {
 
             {
 
                 pos = Handles.PositionHandle(pos, Quaternion.identity);
 
                 pos = Handles.PositionHandle(pos, Quaternion.identity);
Line 227: Line 272:
 
               isEventUsedByHandle)
 
               isEventUsedByHandle)
 
             {
 
             {
                 index = i;
+
                 curPointIndex = i;
 
             }
 
             }
 
           
 
  
 
             polyLine.positions[i] = tr.InverseTransformPoint(pos);
 
             polyLine.positions[i] = tr.InverseTransformPoint(pos);
 
             globalPos[i] = pos;
 
             globalPos[i] = pos;
 
         }
 
         }
 
 
         insideSceneGUI(polyLine);
 
         insideSceneGUI(polyLine);
 
 
      // Debug.Log();
 
 
 
         Handles.DrawPolyLine(globalPos);
 
         Handles.DrawPolyLine(globalPos);
 
     }
 
     }
Line 247: Line 285:
 
     {
 
     {
 
         base.OnInspectorGUI();
 
         base.OnInspectorGUI();
 +
    }
  
     
 
            GUILayout.Label("index " + index);
 
    }
 
 
}
 
}
</csharp>
 
  
And adds a mono behavior like this one that will received the Vector 3 array
 
 
<csharp>
 
using UnityEngine;
 
using System.Collections;
 
 
public class PolyLine : MonoBehaviour
 
{
 
    public Vector3 [] positions;
 
 
// ...
 
}
 
  
 
</csharp>
 
</csharp>

Revision as of 14:18, 10 October 2011

Description

Here is a an exemple of how to use the Unity Handles class and adding custom editing tools.

Exemple Polyline.jpg

This tool adds "inScene" controls to add, remove and align a set of points. those points could be used in any way you want (path, curve, animations ....)

Usage

Add the following class in an Editor directory

C#

<csharp>

using UnityEditor; using UnityEngine; using System.Collections; using System; using System.Reflection;

// Thanks to Dantus from EddelWeiss Interactive for this trick public class DefaultHandles {

   public static bool Hidden
   {
       get
       {
           Type type = typeof(Tools);
           FieldInfo field = type.GetField("s_Hidden", BindingFlags.NonPublic | BindingFlags.Static);
           return ((bool)field.GetValue(null));
       }
       set
       {
           Type type = typeof(Tools);
           FieldInfo field = type.GetField("s_Hidden", BindingFlags.NonPublic | BindingFlags.Static);
           field.SetValue(null, value);
       }
   }

}

[CustomEditor(typeof(PolyLine))] public class PolyLineEditor : Editor {

   Vector3[] globalPos;
  // Event current;
   int curPointIndex = -1;
   bool hideDefaultHandle = true;
   void OnEnable()
   {
       DefaultHandles.Hidden = hideDefaultHandle;
   }
   void OnDisable()
   {
       DefaultHandles.Hidden = false;
   }
   void Delete(PolyLine polyLine, int index)
   {
       if (index < 0 || index >= polyLine.positions.Length)
           return;
       ArrayList list = new ArrayList(polyLine.positions);
       list.RemoveAt(index);
       polyLine.positions = (Vector3 []) list.ToArray(typeof(Vector3));
   }
   void insert(PolyLine polyLine, int position)
   {
       ArrayList list = new ArrayList(polyLine.positions);


       if (polyLine.positions.Length == 0)
       {
           list.Add(Vector3.zero);
       }
       else if (polyLine.positions.Length == 1)
       {
       
           if (position == 0)
           {
               list.Insert(0, Vector3.zero);      
           }
           else
           {
               list.Add(polyLine.positions[0] * 2);      
           }
          
       }
       else
       {
           Vector3[] newArray = new Vector3[polyLine.positions.Length+1];
           if (position == -1 ) // last
               position = polyLine.positions.Length ;
           if (position == 0)
               list.Insert(0, Vector3.zero);      
           else if ( position == polyLine.positions.Length)
               list.Add(2 * polyLine.positions[position - 1] - polyLine.positions[position - 2]);
           else
           {
               // between 2 points, use middle
               list.Insert(position, 0.5f * (polyLine.positions[position - 1] + polyLine.positions[position]));
           }    
       }
       polyLine.positions = (Vector3 []) list.ToArray(typeof(Vector3));
   }
   void insideSceneGUI(PolyLine polyLine)
   {
       Rect size = new Rect(0, 0, 300, 200);
       float sizeButton = 30;
       Handles.BeginGUI();
     //  Handles.BeginGUI(new Rect(Screen.width - size.width - 10, Screen.height - size.height - 10, size.width, size.height));
       GUI.BeginGroup(new Rect(Screen.width - size.width - 10, Screen.height - size.height - 50, size.width, size.height));
       GUI.Box(size, "PolyLine Tool Bar");


       Rect rc = new Rect(0, sizeButton, size.width, sizeButton);
       GUI.Label(rc, "Double Clic on Circles to select a point");
       rc.y += sizeButton;
       if (curPointIndex != -1)
       {
           GUI.Label(rc, "Current Point " + curPointIndex);
           rc.y += sizeButton;
           rc.width = size.width / 3;


           if (GUI.Button(rc, "Insert Before"))
           {
               insert(polyLine, curPointIndex);
           }
           rc.x += rc.width;
           if (GUI.Button(rc, "Delete"))
           {
               Delete(polyLine, curPointIndex);
           }
           rc.x += rc.width;
           if (GUI.Button(rc, "Insert After"))
           {
               insert(polyLine, curPointIndex + 1);
               curPointIndex++;
           }


       }
       else
       {
           if (polyLine.positions.Length == 0)
           {
               if (GUI.Button(rc, "Insert"))
               {
                   insert(polyLine, 0);
               }
               rc.y += sizeButton;
           }
           else
           {
               rc.width = size.width / 2;
               if (GUI.Button(rc, "Insert First"))
               {
                   insert(polyLine, 0);
                   curPointIndex = 0;
               }
               rc.x += rc.width;
               if (GUI.Button(rc, "Insert Last"))
               {
                   insert(polyLine, -1);
                   curPointIndex = polyLine.positions.Length - 1;
               }
               rc.y += sizeButton;
           }
       }
      
       if (polyLine.positions.Length > 0)
       {
           //rc.y += sizeButton;
           rc.width = size.width / 2;
           rc.x = 0;
           rc.y += sizeButton+10;
           if (GUI.Button(rc, "Clear All"))
           {
               polyLine.positions = new Vector3[0];
               curPointIndex = -1;
           }
           rc.x += rc.width;
           if (GUI.Button(rc, "Reset y"))
           {
               for (int i = 0; i < polyLine.positions.Length; i++)
               {
                   polyLine.positions[i].y = 0;
               }
           }
       }
       rc.y += sizeButton + 10;
       rc.x = 0;
       rc.width = size.width;
       if (hideDefaultHandle)
       {
           if (GUI.Button(rc, "Show Main Transform"))
           {
               hideDefaultHandle = false;
               DefaultHandles.Hidden = hideDefaultHandle;
           }
       }
       else
       {
           if (GUI.Button(rc, "Hide Main Transform"))
           {
               hideDefaultHandle = true;
               DefaultHandles.Hidden = hideDefaultHandle;
           }
       }
       
       GUI.EndGroup();
       Handles.EndGUI();
   }
   
   void OnSceneGUI () 
   {
       // Thank to Dantus from Edelweiss for this helper
       // You need them somewhere.
       Quaternion handleRotation = Quaternion.identity;
       int someHashCode = GetHashCode();


       PolyLine polyLine = (PolyLine) target;
       Transform tr = polyLine.transform;
       globalPos = new Vector3[polyLine.positions.Length];
       for (int i = 0; i < polyLine.positions.Length; i++)
       {   
           Vector3 pos = tr.TransformPoint(polyLine.positions[i]);
           Handles.Label(pos, "   " + i);
           float size = HandleUtility.GetHandleSize(pos);
           // Get the needed data before the handle
           int controlIDBeforeHandle = GUIUtility.GetControlID(someHashCode, FocusType.Passive);
           bool isEventUsedBeforeHandle = (Event.current.type == EventType.used);
           //
          // pos = Handles.PositionHandle(pos, Quaternion.identity);
           Handles.ScaleValueHandle(0, pos, Quaternion.identity, size, Handles.SphereCap, 0);
           if (curPointIndex == i)
           {
               pos = Handles.PositionHandle(pos, Quaternion.identity);
           }


           // Get the needed data after the handle
           int controlIDAfterHandle = GUIUtility.GetControlID(someHashCode, FocusType.Passive);
           bool isEventUsedByHandle = !isEventUsedBeforeHandle && (Event.current.type == EventType.used);
           if
            ((controlIDBeforeHandle < GUIUtility.hotControl &&
              GUIUtility.hotControl < controlIDAfterHandle) ||
              isEventUsedByHandle)
           {
               curPointIndex = i;
           }
           polyLine.positions[i] = tr.InverseTransformPoint(pos);
           globalPos[i] = pos;
       }
       insideSceneGUI(polyLine);
       Handles.DrawPolyLine(globalPos);
   }
   override public void  OnInspectorGUI()
   {
       base.OnInspectorGUI();
   }

}


</csharp>

Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox