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