diff --git a/Assets/Scripts/Gameplay/GameplayObjects/Character/EdgePanningController.cs b/Assets/Scripts/Gameplay/GameplayObjects/Character/EdgePanningController.cs index 2cf8a5c1..375411e9 100644 --- a/Assets/Scripts/Gameplay/GameplayObjects/Character/EdgePanningController.cs +++ b/Assets/Scripts/Gameplay/GameplayObjects/Character/EdgePanningController.cs @@ -16,6 +16,13 @@ public class EdgePanningController : MonoBehaviour public float resetSpeed = 2f; // Speed of resetting panning public Vector2 panLimit = new Vector2(0.5f, 0.5f); // Max panning limit (x, y) + // --- Added fields for free roam mode --- + public float freeRoamSpeed = 10f; // Speed of free roam movement + private bool isFreeRoamMode = false; // Toggle for free roam mode + private Vector3 savedCameraPosition; // Stores camera position before free roam + private Quaternion savedCameraRotation; // Stores camera rotation before free roam + private Transform savedFollowTarget; // Stores the original follow target + private Vector3 defaultOffset; private Vector3 panningOffset; private bool isPanning = false; @@ -55,10 +62,73 @@ public class EdgePanningController : MonoBehaviour private void Update() { + // Check for backspace key to toggle free roam mode + if (Input.GetKeyDown(KeyCode.Backspace)) + { + ToggleFreeRoamMode(); + } + + // When in free roam mode, handle free movement and bypass normal edge panning + if (isFreeRoamMode) + { + HandleFreeRoam(); + return; // Skip the rest of Update so the panning logic is not executed + } + + // Normal camera behavior (edge panning) if a target is set if (targetFound) HandleEdgePanning(); } + /// + /// Toggles the free roam mode on/off. + /// + private void ToggleFreeRoamMode() + { + isFreeRoamMode = !isFreeRoamMode; + if (isFreeRoamMode) + { + // Activate free roam: save current camera state and disable following + savedCameraPosition = virtualCamera.transform.position; + savedCameraRotation = virtualCamera.transform.rotation; + savedFollowTarget = virtualCamera.Follow; // Save the current follow target if any + virtualCamera.Follow = null; // Detach so the camera can be controlled directly + } + else + { + // Deactivate free roam: restore the previous camera state and resume following target + virtualCamera.transform.position = savedCameraPosition; + virtualCamera.transform.rotation = savedCameraRotation; + virtualCamera.Follow = savedFollowTarget; // Reattach the follow target + + // Reset panning variables so the camera aligns with its default offset + cameraOffset.m_Offset = defaultOffset; + isPanning = false; + panningOffset = defaultOffset; + } + } + + /// + /// Handles free roam camera movement when free roam mode is active. + /// Uses the Horizontal/Vertical axes and Q/E keys to move up and down. + /// + private void HandleFreeRoam() + { + float horizontal = Input.GetAxis("Horizontal"); // A/D or Left/Right + float vertical = Input.GetAxis("Vertical"); // W/S or Up/Down + + // Use E to ascend and Q to descend (you can change these keys if needed) + float ascent = 0f; + if (Input.GetKey(KeyCode.E)) + ascent = 1f; + else if (Input.GetKey(KeyCode.Q)) + ascent = -1f; + + // Compute movement relative to current camera orientation + Vector3 movement = new Vector3(horizontal, ascent, vertical); + virtualCamera.transform.position += virtualCamera.transform.rotation * movement * freeRoamSpeed * Time.deltaTime; + } + private void HandleEdgePanning() { if (targetCharacter == null) return; @@ -79,28 +149,28 @@ public class EdgePanningController : MonoBehaviour bool isHoveringTarget = IsCursorOverTargetCharacter(); - // ✅ If the cursor touches the center or target **even for a millisecond**, trigger reset + // If the cursor touches the center or target even for a moment, trigger reset if (isNearCenter || isHoveringTarget) { - shouldReset = true; // Set the flag so reset starts immediately + shouldReset = true; } - // ✅ If reset is triggered, smoothly return to default position + // When resetting, smoothly return to the default position if (shouldReset && isPanning) { cameraOffset.m_Offset = Vector3.Lerp(cameraOffset.m_Offset, defaultOffset, Time.deltaTime * resetSpeed); - // ✅ Once back to default, stop resetting and reset flag + // Once the camera gets close enough to default, stop panning and reset the flag if (Vector3.Distance(cameraOffset.m_Offset, defaultOffset) < 0.01f) { isPanning = false; panningOffset = defaultOffset; - shouldReset = false; // Reset flag + shouldReset = false; } return; } - // If cursor is near the edges, start panning (up to limit) + // If the cursor is near the edges, adjust the offset (within limits) if (mousePos.x <= edgeThreshold) newOffset.x = Mathf.Max(defaultOffset.x - panLimit.x, newOffset.x - panSpeed); if (mousePos.x >= screenWidth - edgeThreshold) newOffset.x = Mathf.Min(defaultOffset.x + panLimit.x, newOffset.x + panSpeed); if (mousePos.y <= edgeThreshold) newOffset.y = Mathf.Max(defaultOffset.y - panLimit.y, newOffset.y - panSpeed);