CylinderSurfaceEditor.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using UnityEngine;
  2. using UnityEditor;
  3. using Rokid.UXR.Interaction;
  4. namespace Rokid.UXR.Editor
  5. {
  6. [CustomEditor(typeof(CylinderSurface))]
  7. public class CylinderSurfaceEditor : UnityEditor.Editor
  8. {
  9. private const int NUM_SEGMENTS = 30;
  10. private static readonly Color ValidColor = Color.green * 0.8f;
  11. private static readonly Color InvalidColor = Color.red * 0.8f;
  12. public void OnSceneGUI()
  13. {
  14. CylinderSurface cylinder = target as CylinderSurface;
  15. if (cylinder.Cylinder != null)
  16. {
  17. Draw(cylinder);
  18. }
  19. }
  20. public static void Draw(CylinderSurface cylinderSurface)
  21. {
  22. Color prevColor = Handles.color;
  23. Handles.color = cylinderSurface.IsValid ? ValidColor : InvalidColor;
  24. float gizmoHeight = cylinderSurface.Height;
  25. float camYOffset = 0;
  26. bool infiniteHeight = cylinderSurface.Height <= 0;
  27. if (infiniteHeight && SceneView.lastActiveSceneView?.camera != null)
  28. {
  29. gizmoHeight = 1000f;
  30. Vector3 sceneCamPos = SceneView.lastActiveSceneView.camera.transform.position;
  31. camYOffset = cylinderSurface.Cylinder.transform.InverseTransformPoint(sceneCamPos).y;
  32. }
  33. for (int i = 0; i < 2; ++i)
  34. {
  35. bool isTop = i == 1;
  36. float y = isTop ? gizmoHeight / 2 : -gizmoHeight / 2;
  37. int numSegments = (int)(NUM_SEGMENTS * Mathf.Max(cylinderSurface.Radius / 2, 1));
  38. Vector3 prevSegmentWorld = Vector3.zero;
  39. for (int seg = 0; seg <= numSegments; ++seg)
  40. {
  41. float ratio = (float)seg / numSegments * Mathf.PI * 2;
  42. float x = Mathf.Cos(ratio) * cylinderSurface.Radius;
  43. float z = Mathf.Sin(ratio) * cylinderSurface.Radius;
  44. Vector3 curSegmentLocal = new Vector3(x, y + camYOffset, z);
  45. Vector3 curSegmentWorld = cylinderSurface.Cylinder.transform.TransformPoint(curSegmentLocal);
  46. if (isTop) // Draw connecting lines from top circle
  47. {
  48. Vector3 bottomVert = new Vector3(curSegmentLocal.x,
  49. curSegmentLocal.y - gizmoHeight,
  50. curSegmentLocal.z);
  51. bottomVert = cylinderSurface.Cylinder.transform.TransformPoint(bottomVert);
  52. Handles.DrawLine(curSegmentWorld, bottomVert);
  53. }
  54. if (seg > 0 && !infiniteHeight)
  55. {
  56. Handles.DrawLine(curSegmentWorld, prevSegmentWorld);
  57. }
  58. prevSegmentWorld = curSegmentWorld;
  59. }
  60. }
  61. Handles.color = prevColor;
  62. }
  63. }
  64. }