| | 1 | | using UnityEngine; |
| | 2 | | using System.Collections.Generic; |
| | 3 | | using System; |
| | 4 | |
|
| | 5 | | namespace Builder.Gizmos |
| | 6 | | { |
| | 7 | | public class DCLBuilderGizmoManager : MonoBehaviour |
| | 8 | | { |
| | 9 | | public delegate void GizmoTransformDelegate(string gizmoType); |
| | 10 | |
|
| | 11 | | public static event GizmoTransformDelegate OnGizmoTransformObjectStart; |
| | 12 | | public static event GizmoTransformDelegate OnGizmoTransformObject; |
| | 13 | | public static event GizmoTransformDelegate OnGizmoTransformObjectEnd; |
| | 14 | |
|
| | 15 | | public event Action<Vector3> OnChangeTransformValue; |
| | 16 | |
|
| | 17 | | public DCLBuilderRaycast builderRaycast; |
| | 18 | |
|
| | 19 | | [SerializeField] private DCLBuilderGizmo[] gizmos = null; |
| | 20 | |
|
| 0 | 21 | | public bool isTransformingObject { private set; get; } |
| 0 | 22 | | public DCLBuilderGizmo activeGizmo { private set; get; } |
| | 23 | |
|
| 199 | 24 | | private SnapInfo snapInfo = new SnapInfo(); |
| | 25 | |
|
| | 26 | | private bool isGameObjectActive = false; |
| | 27 | | private bool isGizmosInitialized = false; |
| | 28 | |
|
| | 29 | | private DCLBuilderGizmoAxis hoveredAxis = null; |
| | 30 | |
|
| | 31 | | private Transform selectedEntitiesParent; |
| | 32 | | private List<EditableEntity> selectedEntities; |
| | 33 | |
|
| | 34 | | public string GetSelectedGizmo() |
| | 35 | | { |
| 8 | 36 | | if (IsGizmoActive()) |
| | 37 | | { |
| 6 | 38 | | return activeGizmo.GetGizmoType(); |
| | 39 | | } |
| 2 | 40 | | return DCL.Components.DCLGizmos.Gizmo.NONE; |
| | 41 | | } |
| | 42 | |
|
| | 43 | | public void SetSnapFactor(float position, float rotation, float scale) |
| | 44 | | { |
| 4 | 45 | | snapInfo.position = position; |
| 4 | 46 | | snapInfo.rotation = rotation; |
| 4 | 47 | | snapInfo.scale = scale; |
| | 48 | |
|
| 4 | 49 | | if (activeGizmo != null) |
| | 50 | | { |
| 4 | 51 | | activeGizmo.SetSnapFactor(snapInfo); |
| | 52 | | } |
| 4 | 53 | | } |
| | 54 | |
|
| | 55 | | private void OnBeginDrag(DCLBuilderGizmoAxis hittedAxis) |
| | 56 | | { |
| 0 | 57 | | isTransformingObject = true; |
| 0 | 58 | | activeGizmo = hittedAxis.GetGizmo(); |
| 0 | 59 | | activeGizmo.OnBeginDrag(hittedAxis, selectedEntitiesParent); |
| | 60 | |
|
| 0 | 61 | | OnGizmoTransformObjectStart?.Invoke(activeGizmo.GetGizmoType()); |
| 0 | 62 | | } |
| | 63 | |
|
| | 64 | | private void OnDrag(Vector3 hitPoint, Vector2 mousePosition) |
| | 65 | | { |
| 0 | 66 | | float value = activeGizmo.OnDrag(hitPoint, mousePosition); |
| 0 | 67 | | OnGizmoTransformObject?.Invoke(activeGizmo.GetGizmoType()); |
| 0 | 68 | | OnChangeTransformValue?.Invoke(value * activeGizmo.GetActiveAxisVector()); |
| 0 | 69 | | } |
| | 70 | |
|
| | 71 | | private void OnEndDrag() |
| | 72 | | { |
| 0 | 73 | | activeGizmo.OnEndDrag(); |
| 0 | 74 | | OnGizmoTransformObjectEnd?.Invoke(activeGizmo.GetGizmoType()); |
| 0 | 75 | | isTransformingObject = false; |
| 0 | 76 | | } |
| | 77 | |
|
| 0 | 78 | | public bool HasAxisHover() { return hoveredAxis != null; } |
| | 79 | |
|
| | 80 | | private void SetAxisHover(DCLBuilderGizmoAxis axis) |
| | 81 | | { |
| 11 | 82 | | if (hoveredAxis != null && hoveredAxis != axis) |
| | 83 | | { |
| 0 | 84 | | hoveredAxis.SetColorDefault(); |
| 0 | 85 | | } |
| 11 | 86 | | else if (axis != null) |
| | 87 | | { |
| 0 | 88 | | axis.SetColorHighlight(); |
| | 89 | | } |
| 11 | 90 | | hoveredAxis = axis; |
| 11 | 91 | | } |
| | 92 | |
|
| | 93 | | public void ForceRelativeScaleRatio() |
| | 94 | | { |
| 32 | 95 | | for (int i = 0; i < gizmos.Length; i++) |
| | 96 | | { |
| 12 | 97 | | gizmos[i].ForceRelativeScaleRatio(); |
| | 98 | | } |
| 4 | 99 | | } |
| | 100 | |
|
| | 101 | | public void ShowGizmo() |
| | 102 | | { |
| 0 | 103 | | if (activeGizmo != null) |
| | 104 | | { |
| 0 | 105 | | activeGizmo.SetTargetTransform(selectedEntitiesParent); |
| 0 | 106 | | activeGizmo.gameObject.SetActive(true); |
| | 107 | | } |
| 0 | 108 | | } |
| | 109 | |
|
| | 110 | | public void HideGizmo(bool setInactiveGizmos = false) |
| | 111 | | { |
| 29 | 112 | | if (activeGizmo != null) |
| | 113 | | { |
| 20 | 114 | | activeGizmo.gameObject.SetActive(false); |
| | 115 | | } |
| 29 | 116 | | if (setInactiveGizmos) |
| | 117 | | { |
| 1 | 118 | | SetGizmoType(DCL.Components.DCLGizmos.Gizmo.NONE); |
| | 119 | | } |
| 29 | 120 | | } |
| | 121 | |
|
| 22 | 122 | | private bool IsGizmoActive() { return activeGizmo != null; } |
| | 123 | |
|
| | 124 | | private bool RaycastHit(Ray ray, out Vector3 hitPoint) |
| | 125 | | { |
| 0 | 126 | | if (activeGizmo != null) |
| | 127 | | { |
| 0 | 128 | | return activeGizmo.RaycastHit(ray, out hitPoint); |
| | 129 | | } |
| 0 | 130 | | hitPoint = Vector3.zero; |
| 0 | 131 | | return false; |
| | 132 | | } |
| | 133 | |
|
| | 134 | | private void OnEnable() |
| | 135 | | { |
| 1 | 136 | | if (!isGameObjectActive) |
| | 137 | | { |
| 1 | 138 | | DCLBuilderBridge.OnSelectGizmo += SetGizmoType; |
| 1 | 139 | | DCLBuilderBridge.OnSetGridResolution += OnSetGridResolution; |
| 1 | 140 | | DCLBuilderCamera.OnCameraZoomChanged += OnCameraZoomChanged; |
| 1 | 141 | | DCLBuilderObjectSelector.OnSelectedObjectListChanged += SetSelectedEntities; |
| 1 | 142 | | DCLBuilderObjectSelector.OnGizmosAxisPressed += OnGizmosAxisPressed; |
| 1 | 143 | | DCLBuilderInput.OnMouseUp += OnMouseUp; |
| 1 | 144 | | DCLBuilderInput.OnMouseDrag += OnMouseDrag; |
| 1 | 145 | | isGameObjectActive = true; |
| | 146 | | } |
| 1 | 147 | | } |
| | 148 | |
|
| | 149 | | private void OnDisable() |
| | 150 | | { |
| 1 | 151 | | DCLBuilderBridge.OnSelectGizmo -= SetGizmoType; |
| 1 | 152 | | DCLBuilderBridge.OnSetGridResolution -= OnSetGridResolution; |
| 1 | 153 | | DCLBuilderCamera.OnCameraZoomChanged -= OnCameraZoomChanged; |
| 1 | 154 | | DCLBuilderObjectSelector.OnSelectedObjectListChanged -= SetSelectedEntities; |
| 1 | 155 | | DCLBuilderObjectSelector.OnGizmosAxisPressed -= OnGizmosAxisPressed; |
| 1 | 156 | | DCLBuilderInput.OnMouseUp -= OnMouseUp; |
| 1 | 157 | | DCLBuilderInput.OnMouseDrag -= OnMouseDrag; |
| 1 | 158 | | isGameObjectActive = false; |
| 1 | 159 | | } |
| | 160 | |
|
| | 161 | | private void Update() |
| | 162 | | { |
| 11 | 163 | | if (!isTransformingObject) |
| | 164 | | { |
| 11 | 165 | | CheckGizmoHover(Input.mousePosition); |
| | 166 | | } |
| 11 | 167 | | } |
| | 168 | |
|
| | 169 | | public void SetGizmoType(string gizmoType) |
| | 170 | | { |
| 8 | 171 | | HideGizmo(); |
| | 172 | |
|
| 8 | 173 | | if (gizmoType != DCL.Components.DCLGizmos.Gizmo.NONE) |
| | 174 | | { |
| 7 | 175 | | bool wasGizmoActive = IsGizmoActive(); |
| | 176 | |
|
| 26 | 177 | | for (int i = 0; i < gizmos.Length; i++) |
| | 178 | | { |
| 13 | 179 | | if (gizmos[i].GetGizmoType() == gizmoType) |
| | 180 | | { |
| 7 | 181 | | activeGizmo = gizmos[i]; |
| 7 | 182 | | activeGizmo.SetSnapFactor(snapInfo); |
| 7 | 183 | | break; |
| | 184 | | } |
| | 185 | | } |
| | 186 | |
|
| 7 | 187 | | bool areEntitiesSelected = selectedEntities != null && selectedEntities.Count > 0; |
| 7 | 188 | | if (wasGizmoActive && areEntitiesSelected) |
| | 189 | | { |
| 0 | 190 | | ShowGizmo(); |
| 0 | 191 | | } |
| | 192 | | else |
| | 193 | | { |
| 7 | 194 | | GizmoStatusUpdate(); |
| | 195 | | } |
| 7 | 196 | | } |
| | 197 | | else |
| | 198 | | { |
| 1 | 199 | | activeGizmo = null; |
| | 200 | | } |
| 1 | 201 | | } |
| | 202 | |
|
| 0 | 203 | | public void InitializeGizmos(Camera camera) { InitializeGizmos(camera, camera.transform); } |
| | 204 | |
|
| | 205 | | public void InitializeGizmos(Camera camera, Transform cameraTransform) |
| | 206 | | { |
| 4 | 207 | | if (!isGizmosInitialized) |
| | 208 | | { |
| 8 | 209 | | for (int i = 0; i < gizmos.Length; i++) |
| | 210 | | { |
| 3 | 211 | | if (!gizmos[i].initialized) |
| | 212 | | { |
| 3 | 213 | | gizmos[i].Initialize(camera, cameraTransform); |
| | 214 | | } |
| | 215 | | } |
| 1 | 216 | | isGizmosInitialized = true; |
| | 217 | | } |
| 4 | 218 | | } |
| | 219 | |
|
| 0 | 220 | | private void OnCameraZoomChanged(Camera camera, float zoom) { InitializeGizmos(camera); } |
| | 221 | |
|
| 0 | 222 | | private void OnSetGridResolution(float position, float rotation, float scale) { SetSnapFactor(position, rotation |
| | 223 | |
|
| | 224 | | public void SetSelectedEntities(Transform selectionParent, List<EditableEntity> entities) |
| | 225 | | { |
| 0 | 226 | | selectedEntities = entities; |
| 0 | 227 | | selectedEntitiesParent = selectionParent; |
| 0 | 228 | | GizmoStatusUpdate(); |
| 0 | 229 | | } |
| 0 | 230 | | private void OnGizmosAxisPressed(DCLBuilderGizmoAxis pressedAxis) { OnBeginDrag(pressedAxis); } |
| | 231 | |
|
| | 232 | | private void OnMouseUp(int buttonId, Vector3 mousePosition) |
| | 233 | | { |
| 0 | 234 | | if (!isTransformingObject) |
| | 235 | | { |
| 0 | 236 | | return; |
| | 237 | | } |
| | 238 | |
|
| 0 | 239 | | if (buttonId == 0) |
| | 240 | | { |
| 0 | 241 | | OnEndDrag(); |
| | 242 | | } |
| 0 | 243 | | } |
| | 244 | |
|
| | 245 | | private void OnMouseDrag(int buttonId, Vector3 mousePosition, float axisX, float axisY) |
| | 246 | | { |
| 0 | 247 | | if (buttonId == 0) |
| | 248 | | { |
| 0 | 249 | | bool hasMouseMoved = (axisX != 0 || axisY != 0); |
| 0 | 250 | | if (isTransformingObject && hasMouseMoved) |
| | 251 | | { |
| | 252 | | Vector3 hit; |
| 0 | 253 | | if (RaycastHit(builderRaycast.GetMouseRay(mousePosition), out hit)) |
| | 254 | | { |
| 0 | 255 | | OnDrag(hit, mousePosition); |
| | 256 | | } |
| | 257 | | } |
| | 258 | | } |
| 0 | 259 | | } |
| | 260 | |
|
| | 261 | | private void CheckGizmoHover(Vector3 mousePosition) |
| | 262 | | { |
| | 263 | | RaycastHit hit; |
| 11 | 264 | | if (builderRaycast.RaycastToGizmos(mousePosition, out hit)) |
| | 265 | | { |
| 0 | 266 | | DCLBuilderGizmoAxis gizmoAxis = hit.collider.gameObject.GetComponent<DCLBuilderGizmoAxis>(); |
| 0 | 267 | | SetAxisHover(gizmoAxis); |
| 0 | 268 | | } |
| | 269 | | else |
| | 270 | | { |
| 11 | 271 | | SetAxisHover(null); |
| | 272 | | } |
| 11 | 273 | | } |
| | 274 | |
|
| | 275 | | private void GizmoStatusUpdate() |
| | 276 | | { |
| 7 | 277 | | if (IsGizmoActive()) |
| | 278 | | { |
| 7 | 279 | | if (selectedEntities == null || selectedEntities.Count == 0) |
| | 280 | | { |
| 7 | 281 | | HideGizmo(); |
| 7 | 282 | | } |
| | 283 | | else |
| | 284 | | { |
| 0 | 285 | | ShowGizmo(); |
| | 286 | | } |
| | 287 | | } |
| 0 | 288 | | } |
| | 289 | |
|
| | 290 | | public class SnapInfo |
| | 291 | | { |
| | 292 | | public float position = 0; |
| | 293 | | public float rotation = 0; |
| | 294 | | public float scale = 0; |
| | 295 | | } |
| | 296 | | } |
| | 297 | | } |