Initial import
This commit is contained in:
106
Assets/Scripts/Hybrid/RTSCameraController.cs
Normal file
106
Assets/Scripts/Hybrid/RTSCameraController.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace EE2Clone.Hybrid
|
||||
{
|
||||
/// <summary>
|
||||
/// RTS-style camera controller. Supports WASD/arrow pan, edge-of-screen pan,
|
||||
/// scroll zoom, and Q/E rotation. Client-side only (MonoBehaviour).
|
||||
/// </summary>
|
||||
public class RTSCameraController : MonoBehaviour
|
||||
{
|
||||
[Header("Movement")]
|
||||
[SerializeField] private float panSpeed = 30f;
|
||||
[SerializeField] private float edgePanThreshold = 15f;
|
||||
[SerializeField] private bool enableEdgePan = true;
|
||||
|
||||
[Header("Zoom")]
|
||||
[SerializeField] private float zoomSpeed = 10f;
|
||||
[SerializeField] private float minZoomHeight = 10f;
|
||||
[SerializeField] private float maxZoomHeight = 80f;
|
||||
|
||||
[Header("Rotation")]
|
||||
[SerializeField] private float rotateSpeed = 100f;
|
||||
|
||||
[Header("Bounds")]
|
||||
[SerializeField] private Vector2 mapMin = new(-128f, -128f);
|
||||
[SerializeField] private Vector2 mapMax = new(128f, 128f);
|
||||
|
||||
private Transform _cameraTransform;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_cameraTransform = transform;
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
var input = RTSInputActions.Instance;
|
||||
if (input == null) return;
|
||||
|
||||
HandlePan(input);
|
||||
HandleZoom(input);
|
||||
HandleRotation(input);
|
||||
ClampPosition();
|
||||
}
|
||||
|
||||
private void HandlePan(RTSInputActions input)
|
||||
{
|
||||
var panInput = input.CameraPan;
|
||||
var panDir = new Vector3(panInput.x, 0f, panInput.y);
|
||||
|
||||
// Edge-of-screen panning
|
||||
if (enableEdgePan)
|
||||
{
|
||||
var mousePos = input.MousePosition;
|
||||
if (mousePos.x <= edgePanThreshold) panDir.x -= 1f;
|
||||
if (mousePos.x >= Screen.width - edgePanThreshold) panDir.x += 1f;
|
||||
if (mousePos.y <= edgePanThreshold) panDir.z -= 1f;
|
||||
if (mousePos.y >= Screen.height - edgePanThreshold) panDir.z += 1f;
|
||||
}
|
||||
|
||||
if (panDir.sqrMagnitude > 0.01f)
|
||||
{
|
||||
panDir.Normalize();
|
||||
// Move relative to camera's forward (ignoring Y)
|
||||
var forward = _cameraTransform.forward;
|
||||
forward.y = 0f;
|
||||
forward.Normalize();
|
||||
var right = _cameraTransform.right;
|
||||
right.y = 0f;
|
||||
right.Normalize();
|
||||
|
||||
var move = (forward * panDir.z + right * panDir.x) * (panSpeed * Time.unscaledDeltaTime);
|
||||
_cameraTransform.position += move;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleZoom(RTSInputActions input)
|
||||
{
|
||||
var zoomInput = input.CameraZoom;
|
||||
if (Mathf.Abs(zoomInput) > 0.01f)
|
||||
{
|
||||
var pos = _cameraTransform.position;
|
||||
pos.y -= zoomInput * zoomSpeed * Time.unscaledDeltaTime;
|
||||
pos.y = Mathf.Clamp(pos.y, minZoomHeight, maxZoomHeight);
|
||||
_cameraTransform.position = pos;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleRotation(RTSInputActions input)
|
||||
{
|
||||
var rotateInput = input.CameraRotate;
|
||||
if (Mathf.Abs(rotateInput) > 0.01f)
|
||||
{
|
||||
_cameraTransform.Rotate(Vector3.up, rotateInput * rotateSpeed * Time.unscaledDeltaTime, Space.World);
|
||||
}
|
||||
}
|
||||
|
||||
private void ClampPosition()
|
||||
{
|
||||
var pos = _cameraTransform.position;
|
||||
pos.x = Mathf.Clamp(pos.x, mapMin.x, mapMax.x);
|
||||
pos.z = Mathf.Clamp(pos.z, mapMin.y, mapMax.y);
|
||||
_cameraTransform.position = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user