static Vector3 MoveHandlesGUI(Rect rect, Vector3 pivot, Quaternion rotation)
{
int id = GUIUtility.GetControlID(s_MoveHandleHash, FocusType.Passive);
Vector3 newPos = pivot;
float discSize = HandleUtility.GetHandleSize(pivot) * 0.2f;
float discOpacity = (1 - GUI.color.a);
Vector3[] corners = new Vector3[4];
corners[0] = rotation * new Vector2(rect.x, rect.y) + pivot;
corners[1] = rotation * new Vector2(rect.xMax, rect.y) + pivot;
corners[2] = rotation * new Vector2(rect.xMax, rect.yMax) + pivot;
corners[3] = rotation * new Vector2(rect.x, rect.yMax) + pivot;
VertexSnapping.HandleMouseMove(id);
bool supportsRectSnapping = Selection.transforms.Length == 1 &&
UnityEditorInternal.InternalEditorUtility.SupportsRectLayout(Selection.activeTransform) &&
Selection.activeTransform.parent.rotation == rotation;
Event evt = Event.current;
EventType eventType = evt.GetTypeForControl(id);
Plane guiPlane = new Plane(corners[0], corners[1], corners[2]);
switch (eventType)
{
case EventType.MouseDown:
{
bool acceptClick = false;
if (Tools.vertexDragging)
{
acceptClick = true;
}
else
{
acceptClick =
evt.button == 0 &&
evt.modifiers == 0 &&
RectHandles.RaycastGUIPointToWorldHit(evt.mousePosition, guiPlane, out s_StartMouseWorldPos) &&
(
SceneViewDistanceToRectangle(corners, evt.mousePosition) == 0f ||
(discOpacity > 0 && SceneViewDistanceToDisc(pivot, rotation * Vector3.forward, discSize, evt.mousePosition) == 0f)
);
}
if (acceptClick)
{
s_StartPosition = pivot;
s_StartMousePos = s_CurrentMousePos = evt.mousePosition;
s_Moving = false;
s_LockAxis = -1;
GUIUtility.hotControl = GUIUtility.keyboardControl = id;
EditorGUIUtility.SetWantsMouseJumping(1);
HandleUtility.ignoreRaySnapObjects = null;
evt.Use();
// Calculate snapping values if applicable
if (supportsRectSnapping)
{
Transform transform = Selection.activeTransform;
RectTransform rectTransform = transform.GetComponent <RectTransform>();
Transform transformParent = transform.parent;
RectTransform rectTransformParent = transformParent.GetComponent <RectTransform>();
s_StartRectPosition = rectTransform.anchoredPosition;
RectTransformSnapping.CalculatePositionSnapValues(transformParent, transform, rectTransformParent, rectTransform);
}
}
break;
}
case EventType.MouseDrag:
{
if (GUIUtility.hotControl == id)
{
s_CurrentMousePos += evt.delta;
if (!s_Moving && (s_CurrentMousePos - s_StartMousePos).magnitude > 3f)
{
s_Moving = true;
// Re-raycast to get start mouse pos when effective dragging starts.
// This prevents a sudden unsnap when the dragging is enabled.
RectHandles.RaycastGUIPointToWorldHit(s_CurrentMousePos, guiPlane, out s_StartMouseWorldPos);
}
if (s_Moving)
{
if (Tools.vertexDragging)
{
if (HandleUtility.ignoreRaySnapObjects == null)
{
Handles.SetupIgnoreRaySnapObjects();
}
Vector3 near;
if (HandleUtility.FindNearestVertex(s_CurrentMousePos, null, out near))
{
// Snap position based on found near vertex
newPos = near;
GUI.changed = true;
}
ManipulationToolUtility.minDragDifference = Vector2.zero;
}
else
{
ManipulationToolUtility.SetMinDragDifferenceForPos(pivot);
Vector3 pos;
if (RectHandles.RaycastGUIPointToWorldHit(s_CurrentMousePos, guiPlane, out pos))
{
Vector3 offset = pos - s_StartMouseWorldPos;
// Snap to axis
if (evt.shift)
{
// Get offset in rect handles space
offset = Quaternion.Inverse(rotation) * offset;
// Determine lock axis if not already set
if (s_LockAxis == -1)
{
s_LockAxis = Mathf.Abs(offset.x) > Mathf.Abs(offset.y) ? 0 : 1;
}
// Cancel mocement on other axis
offset[1 - s_LockAxis] = 0;
// Put offset back in world space
offset = rotation * offset;
}
else
{
s_LockAxis = -1;
}
if (supportsRectSnapping)
{
Transform transformParent = Selection.activeTransform.parent;
Vector3 rectPosition = s_StartRectPosition + transformParent.InverseTransformVector(offset);
rectPosition.z = 0;
Quaternion inverseRotation = Quaternion.Inverse(rotation);
Vector2 snapSize = Vector2.one * HandleUtility.GetHandleSize(newPos) * RectTransformSnapping.kSnapThreshold;
snapSize.x /= (inverseRotation * transformParent.TransformVector(Vector3.right)).x;
snapSize.y /= (inverseRotation * transformParent.TransformVector(Vector3.up)).y;
Vector3 newRectPosition = RectTransformSnapping.SnapToGuides(rectPosition, snapSize);
ManipulationToolUtility.DisableMinDragDifferenceBasedOnSnapping(rectPosition, newRectPosition);
offset = transformParent.TransformVector(newRectPosition - s_StartRectPosition);
}
newPos = s_StartPosition + offset;
GUI.changed = true;
}
}
}
evt.Use();
}
break;
}
case EventType.MouseUp:
{
if (GUIUtility.hotControl == id)
{
if (!s_Moving)
{
Selection.activeGameObject = SceneViewPicking.PickGameObject(evt.mousePosition);
}
GUIUtility.hotControl = 0;
EditorGUIUtility.SetWantsMouseJumping(0);
HandleUtility.ignoreRaySnapObjects = null;
evt.Use();
}
break;
}
case EventType.Repaint:
{
if (Tools.vertexDragging)
{
RectHandles.RectScalingHandleCap(id, pivot, rotation, 1, EventType.Repaint);
}
else
{
Handles.color = Handles.secondaryColor * new Color(1, 1, 1, 1.5f * discOpacity);
Handles.CircleHandleCap(id, pivot, rotation, discSize, EventType.Repaint);
Handles.color = Handles.secondaryColor * new Color(1, 1, 1, 0.3f * discOpacity);
Handles.DrawSolidDisc(pivot, rotation * Vector3.forward, discSize);
}
break;
}
}
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingPosX, eventType);
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingLeft, eventType);
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingRight, eventType);
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingPosY, eventType);
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingTop, eventType);
ManipulationToolUtility.DetectDraggingBasedOnMouseDownUp(kChangingBottom, eventType);
return(newPos);
}