ObjectSelectionSnapSession.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using System.Collections.Generic;
  4. namespace O3DWB
  5. {
  6. public class ObjectSelectionSnapSession
  7. {
  8. private enum State
  9. {
  10. Inactive = 0,
  11. SelectPivot,
  12. Snap
  13. }
  14. private List<GameObject> _selectedParents = new List<GameObject>();
  15. private Vector3 _pivot;
  16. private bool _isPivotAvailable;
  17. private State _state;
  18. public bool IsActive { get { return _state != State.Inactive; } }
  19. public void Begin()
  20. {
  21. if (_state != State.Inactive) return;
  22. _state = State.SelectPivot;
  23. _selectedParents = GameObjectExtensions.GetParents(ObjectSelection.Get().GetAllSelectedGameObjects());
  24. }
  25. public void End()
  26. {
  27. _state = State.Inactive;
  28. _selectedParents.Clear();
  29. }
  30. public void RenderGizmos()
  31. {
  32. if(_state != State.Inactive && _isPivotAvailable)
  33. {
  34. Circle2D circle = new Circle2D(Vector3Extensions.WorldToScreenPoint(_pivot), 6.0f);
  35. GizmosEx.Render2DCircleBorderLines(circle, Color.black);
  36. GizmosEx.Render2DFilledCircle(circle, Color.green);
  37. foreach(var parent in _selectedParents)
  38. {
  39. OrientedBox worldOOBB = parent.GetHierarchyWorldOrientedBox();
  40. GizmosEx.RenderOrientedBoxEdges(worldOOBB, Color.yellow);
  41. }
  42. }
  43. }
  44. public void UpdateForMouseMovement()
  45. {
  46. if (_state == State.Inactive) return;
  47. if (MouseButtonStates.Instance.IsMouseButtonDown(MouseButton.Left)) _state = State.Snap;
  48. else _state = State.SelectPivot;
  49. if(_state == State.SelectPivot && _selectedParents.Count != 0)
  50. {
  51. Camera camera = SceneViewCamera.Camera;
  52. Vector2 mousePos = Event.current.InvMousePos(camera);
  53. _isPivotAvailable = false;
  54. float minDistanceSq = float.MaxValue;
  55. foreach (var parent in _selectedParents)
  56. {
  57. if (parent == null) continue;
  58. OrientedBox worldOOBB = parent.GetHierarchyWorldOrientedBox();
  59. if(worldOOBB.IsValid())
  60. {
  61. List<Vector3> centerAndCorners = worldOOBB.GetCenterAndCornerPoints();
  62. List<Vector2> oobbScreenPts = Vector2Extensions.GetScreenPoints(centerAndCorners, camera);
  63. for (int ptIndex = 0; ptIndex < centerAndCorners.Count; ++ptIndex)
  64. {
  65. Vector3 worldPt = centerAndCorners[ptIndex];
  66. Vector2 screenPt = oobbScreenPts[ptIndex];
  67. float distSq = (mousePos - screenPt).sqrMagnitude;
  68. if (distSq < minDistanceSq)
  69. {
  70. minDistanceSq = distSq;
  71. _pivot = worldPt;
  72. _isPivotAvailable = true;
  73. }
  74. }
  75. }
  76. }
  77. }
  78. else
  79. if(_state == State.Snap && _isPivotAvailable)
  80. {
  81. GameObjectExtensions.RecordObjectTransformsForUndo(_selectedParents);
  82. MouseCursorRayHit cursorHit = MouseCursor.Instance.GetCursorRayHitForGridCell();
  83. if (cursorHit.WasACellHit)
  84. {
  85. Camera camera = SceneViewCamera.Camera;
  86. GridCellRayHit cellRayHit = cursorHit.GridCellRayHit;
  87. Vector3 snapDestination = Vector3Extensions.GetClosestPointToPoint(cellRayHit.HitCell.Quad.GetCenterAndCornerPoints(), cellRayHit.HitPoint);
  88. Vector3 moveVector = snapDestination - _pivot;
  89. foreach (var parent in _selectedParents)
  90. {
  91. if (parent != null) parent.transform.position += moveVector;
  92. }
  93. _pivot = snapDestination;
  94. ObjectSelection.Get().ObjectSelectionGizmos.OnObjectSelectionUpdated();
  95. }
  96. }
  97. }
  98. }
  99. }
  100. #endif