mixedreality/com.microsoft.mixedreality..../Services/InputSystem/Editor/NearInteractionTouchableIns...

151 lines
6.6 KiB
C#

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using UnityEditor;
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.Input
{
[CustomEditor(typeof(NearInteractionTouchable), true)]
public class NearInteractionTouchableInspector : NearInteractionTouchableInspectorBase
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
var t = (NearInteractionTouchable)target;
BoxCollider bc = t.GetComponent<BoxCollider>();
RectTransform rt = t.GetComponent<RectTransform>();
if (bc != null)
{
// project size to local coordinate system
Vector2 adjustedSize = new Vector2(
Math.Abs(Vector3.Dot(bc.size, t.LocalRight)),
Math.Abs(Vector3.Dot(bc.size, t.LocalUp)));
// Resize helper
if (adjustedSize != t.Bounds)
{
EditorGUILayout.HelpBox("Bounds do not match the BoxCollider size", MessageType.Warning);
if (GUILayout.Button("Fix Bounds"))
{
Undo.RecordObject(t, "Fix Bounds");
t.SetBounds(adjustedSize);
}
}
// Recentre helper
if (t.LocalCenter != bc.center + Vector3.Scale(bc.size / 2.0f, t.LocalForward))
{
EditorGUILayout.HelpBox("Center does not match the BoxCollider center", MessageType.Warning);
if (GUILayout.Button("Fix Center"))
{
Undo.RecordObject(t, "Fix Center");
t.SetLocalCenter(bc.center + Vector3.Scale(bc.size / 2.0f, t.LocalForward));
}
}
}
else if (rt != null)
{
// Resize Helper
if (rt.sizeDelta != t.Bounds)
{
EditorGUILayout.HelpBox("Bounds do not match the RectTransform size", MessageType.Warning);
if (GUILayout.Button("Fix Bounds"))
{
Undo.RecordObject(t, "Fix Bounds");
t.SetBounds(rt.sizeDelta);
}
}
if (t.GetComponentInParent<Canvas>() != null && t.LocalForward != new Vector3(0, 0, -1))
{
EditorGUILayout.HelpBox("Unity UI generally has forward facing away from the front. The LocalForward direction specified does not match the expected forward direction.", MessageType.Warning);
if (GUILayout.Button("Fix Forward Direction"))
{
Undo.RecordObject(t, "Fix Forward Direction");
t.SetLocalForward(new Vector3(0, 0, -1));
}
}
}
// Perpendicular forward/up vectors helpers
if (!t.AreLocalVectorsOrthogonal)
{
EditorGUILayout.HelpBox("Local Forward and Local Up are not perpendicular.", MessageType.Warning);
if (GUILayout.Button("Fix Local Up"))
{
Undo.RecordObject(t, "Fix Local Up");
t.SetLocalForward(t.LocalForward);
}
if (GUILayout.Button("Fix Local Forward"))
{
Undo.RecordObject(t, "Fix Local Forward");
t.SetLocalUp(t.LocalUp);
}
}
// Warn users when using a non-box collider
if (t.TouchableCollider != null && !(t.TouchableCollider is BoxCollider))
{
if (t.Bounds == Vector2.zero)
{
EditorGUILayout.HelpBox("When using a non-box collider the bounds must be manually specified. The default value (0, 0) will "
+ "not function as intended.\nWith NearInteractionTouchable touch is only detected when the collider is within range of the pointer "
+ "and the pointer is within the 2D bounds specified above. To detect touch with the whole collider (whenever the collider is "
+ "within range of the pointer) use NearInteractionTouchableVolume instead.", MessageType.Warning);
}
else
{
EditorGUILayout.HelpBox("With NearInteractionTouchable touch is only detected when the collider is within range of the pointer "
+ "and the pointer is within the 2D bounds specified above. To detect touch with the whole collider (whenever the collider is "
+ "within range of the pointer) use NearInteractionTouchableVolume instead.", MessageType.Info);
}
}
}
}
[CustomEditor(typeof(BaseNearInteractionTouchable), true)]
public class NearInteractionTouchableInspectorBase : UnityEditor.Editor
{
private readonly Color handleColor = Color.white;
private readonly Color fillColor = new Color(0, 0, 0, 0);
protected virtual void OnSceneGUI()
{
var t = (NearInteractionTouchableSurface)target;
if (Event.current.type == EventType.Repaint)
{
Handles.color = handleColor;
Vector3 center = t.transform.TransformPoint(t.LocalCenter);
float arrowSize = HandleUtility.GetHandleSize(center) * 0.75f;
Handles.ArrowHandleCap(0, center, Quaternion.LookRotation(t.transform.rotation * -t.LocalPressDirection), arrowSize, EventType.Repaint);
var localRight = Vector3.right;
var localUp = Vector3.up;
if (t is NearInteractionTouchable touchableConcrete)
{
localRight = touchableConcrete.LocalRight;
localUp = touchableConcrete.LocalUp;
}
Vector3 rightDelta = t.transform.localToWorldMatrix.MultiplyVector(localRight * t.Bounds.x / 2);
Vector3 upDelta = t.transform.localToWorldMatrix.MultiplyVector(localUp * t.Bounds.y / 2);
Vector3[] points = new Vector3[4];
points[0] = center + rightDelta + upDelta;
points[1] = center - rightDelta + upDelta;
points[2] = center - rightDelta - upDelta;
points[3] = center + rightDelta - upDelta;
Handles.DrawSolidRectangleWithOutline(points, fillColor, handleColor);
}
}
}
}