Files
Frontiers/Source/CameraController.cs

117 lines
2.8 KiB
C#

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;
}
}
}