Files
fgj-26/Scripts/CameraController.cs
T

69 lines
2.1 KiB
C#

using System;
using Godot;
public partial class CameraController : Camera2D
{
[Export] public float ZoomStep = 0.1f;
[Export] public float MinZoom = 0.5f;
[Export] public float MaxZoom = 3.0f;
[Export] private float minX = 0f;
[Export] private float maxX = 0f;
[Export] private float minY = 0f;
[Export] private float maxY = 0f;
private bool _dragging;
private Vector2 _grabWorldPos;
public override void _Input(InputEvent @event)
{
// Middle mouse drag
if (@event is InputEventMouseButton mb)
{
if (mb.ButtonIndex == MouseButton.Middle)
{
_dragging = mb.Pressed;
if (_dragging)
_grabWorldPos = GetGlobalMousePosition();
}
// Scroll zoom
if (mb.Pressed &&
(mb.ButtonIndex == MouseButton.WheelUp ||
mb.ButtonIndex == MouseButton.WheelDown))
{
Vector2 mouseBeforeZoom = GetGlobalMousePosition();
float zoomFactor = mb.ButtonIndex == MouseButton.WheelUp
? -ZoomStep
: ZoomStep;
float newZoom = Mathf.Clamp(Zoom.X + zoomFactor, MinZoom, MaxZoom);
Zoom = new Vector2(newZoom, newZoom);
// keep cursor locked to same world point
Vector2 mouseAfterZoom = GetGlobalMousePosition();
GlobalPosition += mouseBeforeZoom - mouseAfterZoom;
ClampPos();
}
}
if (_dragging && @event is InputEventMouseMotion)
{
Vector2 currentWorld = GetGlobalMousePosition();
GlobalPosition += _grabWorldPos - currentWorld;
ClampPos();
}
}
private void ClampPos()
{
var t = GetCanvasTransform();
var camrect = t.AffineInverse().BasisXform(GetViewportRect().Size);
GlobalPosition = new Vector2(
Mathf.Clamp(GlobalPosition.X, LimitLeft + camrect.X / 2, LimitRight - camrect.X / 2),
Mathf.Clamp(GlobalPosition.Y, LimitTop + camrect.Y / 2, LimitBottom - camrect.Y / 2)
);
}
}