CylinderProximityFieldEditor.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using UnityEditor;
  2. using UnityEngine;
  3. using Rokid.UXR.Interaction;
  4. namespace Rokid.UXR.Editor
  5. {
  6. [CustomEditor(typeof(CylinderProximityField))]
  7. public class CylinderProximityFieldEditor : UnityEditor.Editor
  8. {
  9. private const int SEGMENTS_PER_UNIT = 5;
  10. private SerializedProperty _curvedPlaneProperty;
  11. private void OnEnable()
  12. {
  13. _curvedPlaneProperty = serializedObject.FindProperty("_curvedPlane");
  14. }
  15. public override void OnInspectorGUI()
  16. {
  17. serializedObject.Update();
  18. CylinderProximityField proxField = target as CylinderProximityField;
  19. if (_curvedPlaneProperty.objectReferenceValue != null &&
  20. _curvedPlaneProperty.objectReferenceValue != proxField)
  21. {
  22. GUIStyle italicLabel = new GUIStyle(GUI.skin.label);
  23. italicLabel.fontStyle = FontStyle.Italic;
  24. EditorGUILayout.Space();
  25. EditorGUILayout.LabelField($"{typeof(ICurvedPlane).Name} properties overridden by " +
  26. $"{_curvedPlaneProperty.objectReferenceValue.GetType().Name}", italicLabel);
  27. EditorGUILayout.PropertyField(_curvedPlaneProperty);
  28. }
  29. else
  30. {
  31. DrawDefaultInspector();
  32. }
  33. serializedObject.ApplyModifiedProperties();
  34. }
  35. public void OnSceneGUI()
  36. {
  37. ICurvedPlane curvedPlane = _curvedPlaneProperty.objectReferenceValue as ICurvedPlane;
  38. if (curvedPlane == null)
  39. {
  40. curvedPlane = target as ICurvedPlane;
  41. }
  42. if (curvedPlane.Cylinder == null ||
  43. curvedPlane.ArcDegrees <= 0f)
  44. {
  45. return;
  46. }
  47. Handles.color = EditorConstants.PRIMARY_COLOR;
  48. // Handle infinite height using scene camera Y
  49. float top, bottom;
  50. if (curvedPlane.Top <= curvedPlane.Bottom)
  51. {
  52. if (SceneView.lastActiveSceneView != null &&
  53. SceneView.lastActiveSceneView.camera != null)
  54. {
  55. Vector3 cameraPos =
  56. curvedPlane.Cylinder.transform.InverseTransformPoint(
  57. SceneView.lastActiveSceneView.camera.transform.position);
  58. bottom = cameraPos.y - 10;
  59. top = cameraPos.y + 10;
  60. }
  61. else
  62. {
  63. bottom = -30;
  64. top = 30;
  65. }
  66. }
  67. else
  68. {
  69. bottom = curvedPlane.Bottom;
  70. top = curvedPlane.Top;
  71. }
  72. float height = top - bottom;
  73. float width = curvedPlane.ArcDegrees * Mathf.Deg2Rad * curvedPlane.Cylinder.Radius;
  74. int verticalSegments = Mathf.Max(2, Mathf.CeilToInt(SEGMENTS_PER_UNIT * height));
  75. int horizontalSegments = Mathf.Max(2, Mathf.FloorToInt(SEGMENTS_PER_UNIT * width));
  76. for (int v = 0; v <= verticalSegments; ++v)
  77. {
  78. float y = Mathf.Lerp(bottom, top, (float)v / verticalSegments);
  79. DrawArc(curvedPlane, y);
  80. }
  81. for (int h = 0; h <= horizontalSegments; ++h)
  82. {
  83. float x = Mathf.Lerp(-curvedPlane.ArcDegrees / 2,
  84. curvedPlane.ArcDegrees / 2,
  85. (float)h / horizontalSegments);
  86. DrawLine(curvedPlane, bottom, top, x);
  87. }
  88. }
  89. private void DrawArc(ICurvedPlane curvedPlane, float y)
  90. {
  91. Vector3 center = curvedPlane.Cylinder.transform.TransformPoint(new Vector3(0, y, 0));
  92. Vector3 forward = curvedPlane.Cylinder.transform.TransformDirection(
  93. Quaternion.Euler(0, curvedPlane.Rotation - curvedPlane.ArcDegrees / 2, 0) *
  94. Vector3.forward);
  95. Handles.DrawWireArc(center,
  96. curvedPlane.Cylinder.transform.up,
  97. forward,
  98. curvedPlane.ArcDegrees,
  99. curvedPlane.Cylinder.Radius * curvedPlane.Cylinder.transform.lossyScale.z
  100. #if UNITY_2020_2_OR_NEWER
  101. , EditorConstants.LINE_THICKNESS
  102. #endif
  103. );
  104. }
  105. private void DrawLine(ICurvedPlane curvedPlane, float bottom, float top, float deg)
  106. {
  107. Vector3 forward = Quaternion.Euler(0, curvedPlane.Rotation + deg, 0) *
  108. Vector3.forward * curvedPlane.Cylinder.Radius;
  109. Vector3 p1 = curvedPlane.Cylinder.transform.TransformPoint((Vector3.up * bottom) + forward);
  110. Vector3 p2 = curvedPlane.Cylinder.transform.TransformPoint((Vector3.up * top) + forward);
  111. #if UNITY_2020_2_OR_NEWER
  112. Handles.DrawLine(p1, p2, EditorConstants.LINE_THICKNESS);
  113. #else
  114. Handles.DrawLine(p1, p2);
  115. #endif
  116. }
  117. }
  118. }