using UnityEngine; using UnityEditor; namespace UnityEditor.U2D.Path.GUIFramework { /// /// An implementation of an IGUIState that represents a generic GUI state. /// public class GUIState : IGUIState { private Handles.CapFunction nullCap = (int c, Vector3 p , Quaternion r, float s, EventType ev) => {}; /// /// The current mouse position. /// public Vector2 mousePosition { get { return Event.current.mousePosition; } } /// /// The currently pressed button. /// public int mouseButton { get { return Event.current.button; } } /// /// The current number of mouse clicks. /// public int clickCount { get { return Event.current.clickCount; } set { Event.current.clickCount = Mathf.Max(0, value); } } /// /// Indicates whether the shift key is pressed. /// public bool isShiftDown { get { return Event.current.shift; } } /// /// Indicates whether the alt key is pressed. /// public bool isAltDown { get { return Event.current.alt; } } /// /// Indicates whether the action key is pressed. /// public bool isActionKeyDown { get { return EditorGUI.actionKey; } } /// /// The KeyCode of the currently pressed key. /// public KeyCode keyCode { get { return Event.current.keyCode; } } /// /// The type of the current event. /// public EventType eventType { get { return Event.current.type; } } /// /// The name of the current event's command. /// public string commandName { get { return Event.current.commandName; } } /// /// The closest control to the event. /// public int nearestControl { get { return HandleUtility.nearestControl; } set { HandleUtility.nearestControl = value; } } /// /// Hot Control /// public int hotControl { get { return GUIUtility.hotControl; } set { GUIUtility.hotControl = value; } } /// /// Indicates whether the GUI has changed. /// public bool changed { get { return GUI.changed; } set { GUI.changed = value; } } /// /// Gets the ID of a nested control by a hint and focus type. /// /// The hint this function uses to identify the control ID. /// The focus Type /// Returns the ID of the control that matches the hint and focus type. public int GetControlID(int hint, FocusType focusType) { return GUIUtility.GetControlID(hint, focusType); } /// /// Adds a control to the GUIState. /// /// The ID of the control to add. /// The distance from the camera to the control. public void AddControl(int controlID, float distance) { HandleUtility.AddControl(controlID, distance); } /// /// Checks whether a slider value has changed. /// /// The ID of the slider to check. /// The slider's data. /// The new position of the slider. /// Returns `true` if the slider has changed. Otherwise, returns `false`. public bool Slider(int id, SliderData sliderData, out Vector3 newPosition) { if (mouseButton == 0 && eventType == EventType.MouseDown) { hotControl = 0; nearestControl = id; } EditorGUI.BeginChangeCheck(); newPosition = Handles.Slider2D(id, sliderData.position, sliderData.forward, sliderData.right, sliderData.up, 1f, nullCap, Vector2.zero); return EditorGUI.EndChangeCheck(); } /// /// Uses the current event. /// public void UseEvent() { Event.current.Use(); } /// /// Repaints the GUI. /// public void Repaint() { HandleUtility.Repaint(); } /// /// Checks if the current camera is valid. /// /// Returns `true` if the current camera is not null. Otherwise, returns `false`. public bool HasCurrentCamera() { return Camera.current != null; } /// /// Gets the size of the handle. /// /// The position of the handle. /// Returns the size of the handle. public float GetHandleSize(Vector3 position) { var scale = HasCurrentCamera() ? 0.01f : 0.05f; return HandleUtility.GetHandleSize(position) * scale; } /// /// Measures the GUI-space distance between two points of a segment. /// /// The first point. /// The seconde point. /// Returns the GUI-space distance between p1 and p2. public float DistanceToSegment(Vector3 p1, Vector3 p2) { p1 = HandleUtility.WorldToGUIPoint(p1); p2 = HandleUtility.WorldToGUIPoint(p2); return HandleUtility.DistancePointToLineSegment(Event.current.mousePosition, p1, p2); } /// /// Measures the distance to a circle. /// /// The center of the circle. /// The radius of the circle. /// Returns the distance to a circle with the specified center and radius. public float DistanceToCircle(Vector3 center, float radius) { return HandleUtility.DistanceToCircle(center, radius); } /// /// Transforms a GUI-space position into world space. /// /// The GUI position /// The plane normal. /// The plane position. /// Returns the world-space position of `guiPosition`. public Vector3 GUIToWorld(Vector2 guiPosition, Vector3 planeNormal, Vector3 planePos) { Vector3 worldPos = Handles.inverseMatrix.MultiplyPoint(guiPosition); if (Camera.current) { Ray ray = HandleUtility.GUIPointToWorldRay(guiPosition); planeNormal = Handles.matrix.MultiplyVector(planeNormal); planePos = Handles.matrix.MultiplyPoint(planePos); Plane plane = new Plane(planeNormal, planePos); float distance = 0f; if (plane.Raycast(ray, out distance)) { worldPos = Handles.inverseMatrix.MultiplyPoint(ray.GetPoint(distance)); } } return worldPos; } } }