PolyLineEditor

From Unify Community Wiki
(Difference between revisions)
Jump to: navigation, search
(C#)
(Description)
Line 7: Line 7:
 
This tool adds "inScene" controls to add, remove and align a set of points.
 
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 ....)
 
those points could be used in any way you want (path, curve, animations ....)
 +
 +
 +
I'd like to thank Dantus from EddelWeiss Interactive for 2 very useful trick :
 +
- a way to know which handle I'm currently using
 +
- a way to hide default handle
  
 
==Usage==
 
==Usage==

Revision as of 14:19, 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 ....)


I'd like to thank Dantus from EddelWeiss Interactive for 2 very useful trick : - a way to know which handle I'm currently using - a way to hide default handle

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