91 lines
2.1 KiB
C#
91 lines
2.1 KiB
C#
using Godot;
|
|
using System;
|
|
|
|
public class OrbitCamera : Spatial
|
|
{
|
|
[Export]
|
|
private float _lookSensitivity = 200f;
|
|
[Export]
|
|
private float _zoomSensitivity = 10f;
|
|
[Export]
|
|
private Vector2 _fovRange = new Vector2(10, 60);
|
|
|
|
[Export]
|
|
private NodePath _cameraPath;
|
|
private Camera _camera = null;
|
|
private Camera Camera
|
|
{
|
|
get
|
|
{
|
|
if (_camera == null)
|
|
{
|
|
_camera = GetNode<Camera>(_cameraPath);
|
|
}
|
|
return _camera;
|
|
}
|
|
}
|
|
|
|
private Vector2 _rotation;
|
|
private bool _canRotate = false;
|
|
|
|
public override void _Input(InputEvent e)
|
|
{
|
|
if (e is InputEventMouseMotion mouseMotion)
|
|
{
|
|
HandleMouseMovement(mouseMotion);
|
|
}
|
|
if (e is InputEventMouseButton mouseButton)
|
|
{
|
|
HandleMouseButton(mouseButton);
|
|
}
|
|
}
|
|
|
|
public override void _Process(float delta)
|
|
{
|
|
Rotation = Vector3.Zero;
|
|
var sensitivity = -1f / _lookSensitivity;
|
|
|
|
Rotate(Vector3.Right, _rotation.y * sensitivity);
|
|
Rotate(Vector3.Up, _rotation.x * sensitivity);
|
|
}
|
|
|
|
// left click to drag
|
|
private void HandleMouseButton(InputEventMouseButton mouseButton)
|
|
{
|
|
switch ((ButtonList)mouseButton.ButtonIndex)
|
|
{
|
|
case ButtonList.Left:
|
|
_canRotate = mouseButton.Pressed;
|
|
break;
|
|
case ButtonList.WheelUp:
|
|
Zoom(-1);
|
|
break;
|
|
case ButtonList.WheelDown:
|
|
Zoom(1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void Zoom(int dir)
|
|
{
|
|
if (dir != 1 && dir != -1)
|
|
throw new ArgumentException();
|
|
|
|
var fov = Camera.Fov;
|
|
var zoom = _zoomSensitivity / Camera.Fov;
|
|
|
|
fov += (float)dir * zoom;
|
|
fov = Mathf.Clamp(fov, _fovRange.x, _fovRange.y);
|
|
|
|
Camera.Fov = fov;
|
|
}
|
|
|
|
private void HandleMouseMovement(InputEventMouseMotion mouseMotion)
|
|
{
|
|
if (!_canRotate) return;
|
|
|
|
var delta = mouseMotion.Relative;
|
|
_rotation += delta;
|
|
}
|
|
}
|