using Godot; public partial class CameraController : Camera2D { [Export] public float ZoomSpeed = 1.1f; [Export] public float MinZoom = 0.01f; [Export] public float MaxZoom = 5.0f; [Export] public bool EnableRotation = false; [Export] public float RotationSpeed = 0.01f; [Export] public float PanSmoothing = 0.1f; private bool _isDragging = false; private Vector2 _dragStartMousePos; private Vector2 _dragStartCameraPos; private bool _isRotating = false; private Vector2 _lastMousePosition; public override void _Ready() { Enabled = true; } public override void _UnhandledInput(InputEvent @event) { HandleZoom(@event); HandlePanning(@event); HandleRotation(@event); } private void HandleZoom(InputEvent @event) { if (@event is InputEventMouseButton mouseButton && mouseButton.Pressed) { Vector2 mouseWorldPos = GetGlobalMousePosition(); if (mouseButton.ButtonIndex == MouseButton.WheelUp) { var newZoom = Zoom * ZoomSpeed; if (newZoom.X <= MaxZoom) { ZoomToPoint(newZoom, mouseWorldPos); } } else if (mouseButton.ButtonIndex == MouseButton.WheelDown) { var newZoom = Zoom / ZoomSpeed; if (newZoom.X >= MinZoom) { ZoomToPoint(newZoom, mouseWorldPos); } } } } private void ZoomToPoint(Vector2 newZoom, Vector2 worldPoint) { Vector2 viewportCenter = GetViewportRect().Size / 2; Vector2 offsetFromCenter = (GetGlobalMousePosition() - GlobalPosition); Zoom = newZoom; Vector2 newOffsetFromCenter = offsetFromCenter / (newZoom.X / Zoom.X); GlobalPosition += offsetFromCenter - newOffsetFromCenter; } private void HandlePanning(InputEvent @event) { if (@event is InputEventMouseButton mouseButton) { if (mouseButton.ButtonIndex == MouseButton.Left) { if (mouseButton.Pressed) { _isDragging = true; _dragStartMousePos = mouseButton.GlobalPosition; _dragStartCameraPos = GlobalPosition; } else { _isDragging = false; } } } else if (@event is InputEventMouseMotion mouseMotion && _isDragging) { Vector2 mouseDelta = _dragStartMousePos - mouseMotion.GlobalPosition; GlobalPosition = _dragStartCameraPos + mouseDelta / Zoom; } } private void HandleRotation(InputEvent @event) { if (!EnableRotation) return; if (@event is InputEventMouseButton mouseButton) { if (mouseButton.ButtonIndex == MouseButton.Right) { if (mouseButton.Pressed) { _isRotating = true; _lastMousePosition = mouseButton.GlobalPosition; } else { _isRotating = false; } } } else if (@event is InputEventMouseMotion mouseMotion && _isRotating) { var delta = _lastMousePosition - mouseMotion.GlobalPosition; Rotation += delta.X * RotationSpeed; _lastMousePosition = mouseMotion.GlobalPosition; } } }