/// <summary> /// Unsubscribes from manipulation events. /// </summary> private void OnDisable() { if (objectManipulator != null) { objectManipulator.OnManipulationStarted.RemoveListener(OnManipulationStarted); objectManipulator.OnManipulationEnded.RemoveListener(OnManipulationEnded); objectManipulator = null; } if (manipulationHandler != null) { manipulationHandler.OnManipulationStarted.RemoveListener(OnManipulationStarted); manipulationHandler.OnManipulationEnded.RemoveListener(OnManipulationEnded); manipulationHandler = null; } if (dockedPosition != null) { dockedPosition.DockedObject = null; dockedPosition = null; } overlappingPositions.Clear(); }
/// <summary> /// Undocks this <see cref="Dockable"/> from the current <see cref="DockPosition"/> where it is docked. /// </summary> public void Undock() { if (!CanUndock) { Debug.LogError($"Trying to undock an object that was not docked. State = {dockingState}"); return; } Debug.Log($"Undocking object {gameObject.name} from position {dockedPosition.gameObject.name}"); dockedPosition.DockedObject = null; dockedPosition = null; dockedPositionScale = Vector3.one; dockingState = DockingState.Undocking; }
/// <summary> /// Gets the overlapping <see cref="DockPosition"/> that is closest to this Dockable. /// </summary> /// <returns>The overlapping <see cref="DockPosition"/> that is closest to this <see cref="Dockable"/>, or null if no positions overlap.</returns> private DockPosition GetClosestPosition() { var bounds = gameObject.GetComponent <Collider>().bounds; var minDistance = float.MaxValue; DockPosition closestPosition = null; foreach (var position in overlappingPositions) { var distance = (position.gameObject.GetComponent <Collider>().bounds.center - bounds.center).sqrMagnitude; if (closestPosition == null || distance < minDistance) { closestPosition = position; minDistance = distance; } } return(closestPosition); }
/// <summary> /// Docks this object in a given <see cref="DockPosition"/>. /// </summary> /// <param name="position">The <see cref="DockPosition"/> where we'd like to dock this object.</param> public void Dock(DockPosition position) { if (!CanDock) { Debug.LogError($"Trying to dock an object that was not undocked. State = {dockingState}"); return; } Debug.Log($"Docking object {gameObject.name} on position {position.gameObject.name}"); dockedPosition = position; dockedPosition.DockedObject = this; float scaleToFit = gameObject.GetComponent <Collider>().bounds.GetScaleToFitInside(dockedPosition.GetComponent <Collider>().bounds); dockedPositionScale = transform.localScale * scaleToFit; if (dockingState == DockingState.Undocked) { // Only register the original scale when first docking originalScale = transform.localScale; } dockingState = DockingState.Docking; }
/// <summary> /// Moves elements near the desired position to make space for a new element, /// if possible. /// </summary> /// <param name="position">The desired position where an object wants to be docked.</param> /// <returns>Returns true if the desired position is now available, false otherwise.</returns> public bool TryMoveToFreeSpace(DockPosition position) { if (dockPositions == null) { UpdatePositions(); } if (!dockPositions.Contains(position)) { Debug.LogError("Looking for a DockPosition in the wrong Dock."); return(false); } var index = dockPositions.IndexOf(position); if (!dockPositions[index].IsOccupied) { // Already free return(true); } // Where is the closest free space? (on a tie, favor left) int?closestFreeSpace = null; int distanceToClosestFreeSpace = int.MaxValue; for (int i = 0; i < dockPositions.Count; i++) { var distance = Math.Abs(index - i); if (!dockPositions[i].IsOccupied && distance < distanceToClosestFreeSpace) { closestFreeSpace = i; distanceToClosestFreeSpace = distance; } } if (closestFreeSpace == null) { // No free space return(false); } if (closestFreeSpace < index) { // Move left // Check if we can undock all of them for (int i = closestFreeSpace.Value + 1; i <= index; i++) { if (!dockPositions[i].DockedObject.CanUndock) { return(false); } } for (int i = closestFreeSpace.Value + 1; i <= index; i++) { MoveDockedObject(i, i - 1); } } else { // Move right // Check if we can undock all of them for (int i = closestFreeSpace.Value - 1; i >= index; i--) { if (!dockPositions[i].DockedObject.CanUndock) { return(false); } } for (int i = closestFreeSpace.Value - 1; i >= index; i--) { MoveDockedObject(i, i + 1); } } return(true); }