MyHandles.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using UnityEditor;
  4. public class MyHandles
  5. {
  6. // internal state for DragHandle()
  7. static int s_DragHandleHash = "DragHandleHash".GetHashCode();
  8. static Vector2 s_DragHandleMouseStart;
  9. static Vector2 s_DragHandleMouseCurrent;
  10. static Vector3 s_DragHandleWorldStart;
  11. static float s_DragHandleClickTime = 0;
  12. static int s_DragHandleClickID;
  13. static float s_DragHandleDoubleClickInterval = 0.5f;
  14. static bool s_DragHandleHasMoved;
  15. // externally accessible to get the ID of the most resently processed DragHandle
  16. public static int lastDragHandleID;
  17. public enum DragHandleResult
  18. {
  19. none = 0,
  20. LMBPress,
  21. LMBClick,
  22. LMBDoubleClick,
  23. LMBDrag,
  24. LMBRelease,
  25. RMBPress,
  26. RMBClick,
  27. RMBDoubleClick,
  28. RMBDrag,
  29. RMBRelease,
  30. };
  31. #if UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5
  32. public static Vector3 DragHandle(Vector3 position, float handleSize, Handles.DrawCapFunction capFunc, Color colorSelected, out DragHandleResult result)
  33. #else
  34. public static Vector3 DragHandle(Vector3 position, float handleSize, Handles.CapFunction capFunc, Color colorSelected, out DragHandleResult result)
  35. #endif
  36. {
  37. int id = GUIUtility.GetControlID(s_DragHandleHash, FocusType.Passive);
  38. lastDragHandleID = id;
  39. Vector3 screenPosition = Handles.matrix.MultiplyPoint(new Vector3(position.x, 0, position.z));
  40. Matrix4x4 cachedMatrix = Handles.matrix;
  41. result = DragHandleResult.none;
  42. switch (Event.current.GetTypeForControl(id))
  43. {
  44. case EventType.MouseDown:
  45. if (HandleUtility.nearestControl == id && (Event.current.button == 0 || Event.current.button == 1))
  46. {
  47. GUIUtility.hotControl = id;
  48. s_DragHandleMouseCurrent = s_DragHandleMouseStart = Event.current.mousePosition;
  49. s_DragHandleWorldStart = position;
  50. s_DragHandleHasMoved = false;
  51. Event.current.Use();
  52. EditorGUIUtility.SetWantsMouseJumping(1);
  53. if (Event.current.button == 0)
  54. result = DragHandleResult.LMBPress;
  55. else if (Event.current.button == 1)
  56. result = DragHandleResult.RMBPress;
  57. }
  58. break;
  59. case EventType.MouseUp:
  60. if (GUIUtility.hotControl == id && (Event.current.button == 0 || Event.current.button == 1))
  61. {
  62. GUIUtility.hotControl = 0;
  63. Event.current.Use();
  64. EditorGUIUtility.SetWantsMouseJumping(0);
  65. if (Event.current.button == 0)
  66. result = DragHandleResult.LMBRelease;
  67. else if (Event.current.button == 1)
  68. result = DragHandleResult.RMBRelease;
  69. if (Event.current.mousePosition == s_DragHandleMouseStart)
  70. {
  71. bool doubleClick = (s_DragHandleClickID == id) &&
  72. (Time.realtimeSinceStartup - s_DragHandleClickTime < s_DragHandleDoubleClickInterval);
  73. s_DragHandleClickID = id;
  74. s_DragHandleClickTime = Time.realtimeSinceStartup;
  75. if (Event.current.button == 0)
  76. result = doubleClick ? DragHandleResult.LMBDoubleClick : DragHandleResult.LMBClick;
  77. else if (Event.current.button == 1)
  78. result = doubleClick ? DragHandleResult.RMBDoubleClick : DragHandleResult.RMBClick;
  79. }
  80. }
  81. break;
  82. case EventType.MouseDrag:
  83. if (GUIUtility.hotControl == id)
  84. {
  85. s_DragHandleMouseCurrent += new Vector2(Event.current.delta.x, -Event.current.delta.y);
  86. Vector3 position2 = Camera.current.WorldToScreenPoint(Handles.matrix.MultiplyPoint(s_DragHandleWorldStart))
  87. + (Vector3)(s_DragHandleMouseCurrent - s_DragHandleMouseStart);
  88. position = Handles.matrix.inverse.MultiplyPoint(Camera.current.ScreenToWorldPoint(position2));
  89. if (Camera.current.transform.forward == Vector3.forward || Camera.current.transform.forward == -Vector3.forward)
  90. position.z = s_DragHandleWorldStart.z;
  91. if (Camera.current.transform.forward == Vector3.up || Camera.current.transform.forward == -Vector3.up)
  92. position.y = s_DragHandleWorldStart.y;
  93. if (Camera.current.transform.forward == Vector3.right || Camera.current.transform.forward == -Vector3.right)
  94. position.x = s_DragHandleWorldStart.x;
  95. if (Event.current.button == 0)
  96. result = DragHandleResult.LMBDrag;
  97. else if (Event.current.button == 1)
  98. result = DragHandleResult.RMBDrag;
  99. s_DragHandleHasMoved = true;
  100. GUI.changed = true;
  101. Event.current.Use();
  102. }
  103. break;
  104. case EventType.Repaint:
  105. Color currentColour = Handles.color;
  106. if (id == GUIUtility.hotControl && s_DragHandleHasMoved)
  107. Handles.color = colorSelected;
  108. Handles.matrix = Matrix4x4.identity;
  109. #if UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5
  110. capFunc(id, screenPosition, Quaternion.Euler(0, 0, 0), handleSize);
  111. #else
  112. capFunc(id, screenPosition, Quaternion.Euler(0, 0, 0), handleSize, EventType.Repaint);
  113. #endif
  114. Handles.matrix = cachedMatrix;
  115. Handles.color = currentColour;
  116. break;
  117. case EventType.Layout:
  118. Handles.matrix = Matrix4x4.identity;
  119. HandleUtility.AddControl(id, HandleUtility.DistanceToCircle(screenPosition, handleSize));
  120. Handles.matrix = cachedMatrix;
  121. break;
  122. }
  123. return position;
  124. }
  125. }
  126. #endif