69 lines
2.1 KiB
C#
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)
|
|
);
|
|
}
|
|
} |