feat/teaser-prototype-playable-core (#1)
Co-authored-by: John Lamb <j.lamb13@gmail.com> Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
187
Backyard CTF/Assets/Scripts/CameraController.cs
Normal file
187
Backyard CTF/Assets/Scripts/CameraController.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
public class CameraController : MonoBehaviour
|
||||
{
|
||||
// Zoom settings
|
||||
public float minZoom = 5f;
|
||||
public float maxZoom = 25f;
|
||||
public float zoomSpeed = 2f;
|
||||
public float pinchZoomSpeed = 0.1f;
|
||||
|
||||
// Pan settings
|
||||
public float panSpeed = 1f;
|
||||
|
||||
Camera cam;
|
||||
Vector2 lastPanPosition;
|
||||
bool isPanning;
|
||||
float lastPinchDistance;
|
||||
bool isPinching;
|
||||
|
||||
// Track if we started on a unit (don't pan if drawing route)
|
||||
bool startedOnUnit;
|
||||
|
||||
void Start()
|
||||
{
|
||||
cam = Camera.main;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
HandleMouseInput();
|
||||
HandleTouchInput();
|
||||
ClampCameraPosition();
|
||||
}
|
||||
|
||||
void HandleMouseInput()
|
||||
{
|
||||
var mouse = Mouse.current;
|
||||
if (mouse == null) return;
|
||||
|
||||
// Scroll wheel zoom
|
||||
float scroll = mouse.scroll.ReadValue().y;
|
||||
if (Mathf.Abs(scroll) > 0.01f)
|
||||
{
|
||||
Zoom(-scroll * zoomSpeed * Time.deltaTime * 10f);
|
||||
}
|
||||
|
||||
// Right-click pan (left-click is for route drawing)
|
||||
if (mouse.rightButton.wasPressedThisFrame)
|
||||
{
|
||||
lastPanPosition = mouse.position.ReadValue();
|
||||
isPanning = true;
|
||||
}
|
||||
else if (mouse.rightButton.wasReleasedThisFrame)
|
||||
{
|
||||
isPanning = false;
|
||||
}
|
||||
|
||||
if (isPanning && mouse.rightButton.isPressed)
|
||||
{
|
||||
Vector2 currentPos = mouse.position.ReadValue();
|
||||
Vector2 delta = currentPos - lastPanPosition;
|
||||
Pan(-delta);
|
||||
lastPanPosition = currentPos;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleTouchInput()
|
||||
{
|
||||
var touch = Touchscreen.current;
|
||||
if (touch == null) return;
|
||||
|
||||
int touchCount = 0;
|
||||
foreach (var t in touch.touches)
|
||||
{
|
||||
if (t.press.isPressed) touchCount++;
|
||||
}
|
||||
|
||||
if (touchCount == 2)
|
||||
{
|
||||
// Two finger pinch zoom and pan
|
||||
var touch0 = touch.touches[0];
|
||||
var touch1 = touch.touches[1];
|
||||
|
||||
Vector2 pos0 = touch0.position.ReadValue();
|
||||
Vector2 pos1 = touch1.position.ReadValue();
|
||||
float currentDistance = Vector2.Distance(pos0, pos1);
|
||||
|
||||
if (!isPinching)
|
||||
{
|
||||
isPinching = true;
|
||||
lastPinchDistance = currentDistance;
|
||||
lastPanPosition = (pos0 + pos1) / 2f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pinch zoom
|
||||
float deltaDistance = lastPinchDistance - currentDistance;
|
||||
Zoom(deltaDistance * pinchZoomSpeed);
|
||||
lastPinchDistance = currentDistance;
|
||||
|
||||
// Two-finger pan
|
||||
Vector2 currentCenter = (pos0 + pos1) / 2f;
|
||||
Vector2 delta = currentCenter - lastPanPosition;
|
||||
Pan(-delta);
|
||||
lastPanPosition = currentCenter;
|
||||
}
|
||||
|
||||
isPanning = false; // Don't single-finger pan while pinching
|
||||
}
|
||||
else if (touchCount == 1)
|
||||
{
|
||||
isPinching = false;
|
||||
|
||||
var primaryTouch = touch.primaryTouch;
|
||||
Vector2 touchPos = primaryTouch.position.ReadValue();
|
||||
|
||||
// Check if touch started on a unit
|
||||
if (primaryTouch.press.wasPressedThisFrame)
|
||||
{
|
||||
Vector2 worldPos = cam.ScreenToWorldPoint(touchPos);
|
||||
var hit = Physics2D.OverlapPoint(worldPos);
|
||||
startedOnUnit = hit != null && hit.GetComponent<Unit>() != null;
|
||||
|
||||
if (!startedOnUnit)
|
||||
{
|
||||
lastPanPosition = touchPos;
|
||||
isPanning = true;
|
||||
}
|
||||
}
|
||||
else if (primaryTouch.press.wasReleasedThisFrame)
|
||||
{
|
||||
isPanning = false;
|
||||
startedOnUnit = false;
|
||||
}
|
||||
|
||||
// Single finger pan (only if not drawing route)
|
||||
if (isPanning && !startedOnUnit && primaryTouch.press.isPressed)
|
||||
{
|
||||
Vector2 delta = touchPos - lastPanPosition;
|
||||
Pan(-delta);
|
||||
lastPanPosition = touchPos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isPinching = false;
|
||||
isPanning = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Zoom(float delta)
|
||||
{
|
||||
float newSize = cam.orthographicSize + delta;
|
||||
cam.orthographicSize = Mathf.Clamp(newSize, minZoom, maxZoom);
|
||||
}
|
||||
|
||||
void Pan(Vector2 screenDelta)
|
||||
{
|
||||
// Convert screen delta to world delta
|
||||
float worldUnitsPerPixel = cam.orthographicSize * 2f / Screen.height;
|
||||
Vector3 worldDelta = new Vector3(
|
||||
screenDelta.x * worldUnitsPerPixel * panSpeed,
|
||||
screenDelta.y * worldUnitsPerPixel * panSpeed,
|
||||
0
|
||||
);
|
||||
|
||||
cam.transform.position += worldDelta;
|
||||
}
|
||||
|
||||
void ClampCameraPosition()
|
||||
{
|
||||
// Keep camera within map bounds (with some padding for zoom)
|
||||
float halfHeight = cam.orthographicSize;
|
||||
float halfWidth = halfHeight * cam.aspect;
|
||||
|
||||
float minX = -Game.MapWidth / 2f + halfWidth;
|
||||
float maxX = Game.MapWidth / 2f - halfWidth;
|
||||
float minY = -Game.MapHeight / 2f + halfHeight;
|
||||
float maxY = Game.MapHeight / 2f - halfHeight;
|
||||
|
||||
Vector3 pos = cam.transform.position;
|
||||
pos.x = Mathf.Clamp(pos.x, minX, maxX);
|
||||
pos.y = Mathf.Clamp(pos.y, minY, maxY);
|
||||
cam.transform.position = pos;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user