ObjectSelectionObject2ObjectSnapSession.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using System.Collections.Generic;
  4. namespace O3DWB
  5. {
  6. public class ObjectSelectionObject2ObjectSnapSession
  7. {
  8. private bool _isActive;
  9. private float _snapEpsilon = 0.5f;
  10. private List<GameObject> _selectedParents = new List<GameObject>();
  11. private List<GameObject> _allSelectedObjects = new List<GameObject>();
  12. private ObjectMask _rayCastObjectMask = new ObjectMask();
  13. public bool IsActive { get { return _isActive; } }
  14. public float SnapEpsilon { get { return _snapEpsilon; } set { _snapEpsilon = Mathf.Max(1e-5f, value); } }
  15. public void Begin()
  16. {
  17. if (_isActive) return;
  18. _allSelectedObjects = ObjectSelection.Get().GetAllSelectedGameObjects();
  19. _selectedParents = GameObjectExtensions.GetParents(_allSelectedObjects);
  20. _rayCastObjectMask.ObjectCollectionMask.Mask(_allSelectedObjects);
  21. _isActive = true;
  22. }
  23. public void End()
  24. {
  25. if(_isActive)
  26. {
  27. _isActive = false;
  28. _selectedParents.Clear();
  29. _allSelectedObjects.Clear();
  30. _rayCastObjectMask.ObjectCollectionMask.UnmaskAll();
  31. }
  32. }
  33. public void UpdateOnMouseMove()
  34. {
  35. if(_isActive)
  36. {
  37. MouseCursorRayHit cursorRayHit = GetCursorRayHit();
  38. if (cursorRayHit == null || !cursorRayHit.WasAnythingHit) return;
  39. Vector3 hitPoint = Vector3.zero;
  40. Vector3 hitNormal = Vector3.zero;
  41. if (!cursorRayHit.WasAnObjectHit && cursorRayHit.WasACellHit)
  42. {
  43. hitPoint = cursorRayHit.GridCellRayHit.HitPoint;
  44. hitNormal = cursorRayHit.GridCellRayHit.HitNormal;
  45. }
  46. else
  47. if (cursorRayHit.WasAnObjectHit && !cursorRayHit.WasACellHit)
  48. {
  49. hitPoint = cursorRayHit.ClosestObjectRayHit.HitPoint;
  50. hitNormal = cursorRayHit.ClosestObjectRayHit.HitNormal;
  51. }
  52. else
  53. if(cursorRayHit.WasAnObjectHit && cursorRayHit.WasACellHit)
  54. {
  55. if(cursorRayHit.ClosestObjectRayHit.HitEnter < cursorRayHit.GridCellRayHit.HitEnter)
  56. {
  57. hitPoint = cursorRayHit.ClosestObjectRayHit.HitPoint;
  58. hitNormal = cursorRayHit.ClosestObjectRayHit.HitNormal;
  59. }
  60. else
  61. {
  62. hitPoint = cursorRayHit.GridCellRayHit.HitPoint;
  63. hitNormal = cursorRayHit.GridCellRayHit.HitNormal;
  64. }
  65. }
  66. Plane hitPlane = new Plane(hitNormal, hitPoint);
  67. Box selectionWorldAABB = ObjectSelection.Get().GetWorldBox();
  68. if (selectionWorldAABB.IsInvalid()) return;
  69. Vector3 oldCenter = selectionWorldAABB.Center;
  70. selectionWorldAABB.Center = hitPoint;
  71. selectionWorldAABB.MoveInFrontOfPlane(hitPlane);
  72. Vector3 moveVector = selectionWorldAABB.Center - oldCenter;
  73. float snapEps = ObjectSelection.Get().Settings.Object2ObjectSnapSettings.SnapEps;
  74. GameObjectExtensions.RecordObjectTransformsForUndo(_selectedParents);
  75. foreach(var parent in _selectedParents)
  76. {
  77. parent.transform.position += moveVector;
  78. }
  79. var ignoreObjects = new List<GameObject>(_allSelectedObjects);
  80. ignoreObjects.AddRange(ObjectSnapping.Get().ObjectSnapMask.ObjectCollectionMask.GetAllMaskedGameObjects());
  81. Object2ObjectSnap.Snap(_selectedParents, snapEps, ignoreObjects);
  82. }
  83. }
  84. private MouseCursorRayHit GetCursorRayHit()
  85. {
  86. if (!ObjectSelection.Get().Settings.Object2ObjectSnapSettings.CanHoverObjects)
  87. MouseCursor.Instance.PushObjectPickMaskFlags(MouseCursorObjectPickFlags.ObjectTerrain | MouseCursorObjectPickFlags.ObjectMesh | MouseCursorObjectPickFlags.ObjectBox | MouseCursorObjectPickFlags.ObjectSprite);
  88. else
  89. MouseCursor.Instance.PushObjectPickMaskFlags(MouseCursorObjectPickFlags.ObjectTerrain | MouseCursorObjectPickFlags.ObjectMesh);
  90. MouseCursor.Instance.PushObjectMask(_rayCastObjectMask);
  91. MouseCursorRayHit cursorRayHit = MouseCursor.Instance.GetRayHit();
  92. MouseCursor.Instance.PopObjectMask();
  93. MouseCursor.Instance.PopObjectPickMaskFlags();
  94. return cursorRayHit;
  95. }
  96. }
  97. }
  98. #endif