Files
FoodFactory/src/VoxelGrid/RTSCameraController.cs

150 lines
3.4 KiB
C#

namespace FoodFactory;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
[Meta(typeof(IAutoNode))]
public partial class RTSCameraController : Node3D
{
public override void _Notification(int what) => this.Notify(what);
[Export] public float MoveSpeed = 20f;
[Export] public float RotationSpeed = 90f;
[Export] public float ZoomSpeed = 5f;
[Export] public float MinZoom = 5f;
[Export] public float MaxZoom = 50f;
[Export] public float HeightSpeed = 10f;
[Node("YawPivot")]
private Node3D _yawPivot{get;set;} = default!;
[Node("YawPivot/PitchPivent")]
private Node3D _pitchPivot{get;set;} = default!;
[Node("YawPivot/PitchPivent/Camera3D")]
private Camera3D _camera{get;set;} = default!;
private float _zoomDistance = 20f;
private bool _freeLook = false;
public override void _Ready()
{
// _yawPivot = GetNode<Node3D>("YawPivot");
// _pitchPivot = _yawPivot.GetNode<Node3D>("PitchPivot");
// _camera = _pitchPivot.GetNode<Camera3D>("Camera3D");
UpdateZoom();
}
public override void _Process(double delta)
{
float dt = (float)delta;
HandleMovement(dt);
HandleRotation(dt);
HandleHeight(dt);
}
private void HandleMovement(float dt)
{
Vector3 move = Vector3.Zero;
if (Input.IsActionPressed("move_forward"))
move -= _yawPivot.GlobalBasis.Z;
if (Input.IsActionPressed("move_back"))
move += _yawPivot.GlobalBasis.Z;
if (Input.IsActionPressed("move_left"))
move -= _yawPivot.GlobalBasis.X;
if (Input.IsActionPressed("move_right"))
move += _yawPivot.GlobalBasis.X;
move.Y = 0;
move = move.Normalized();
GlobalPosition += move * MoveSpeed * dt;
}
private void HandleRotation(float dt)
{
if (Input.IsActionPressed("rotate_left"))
RotateY(Mathf.DegToRad(RotationSpeed * dt));
if (Input.IsActionPressed("rotate_right"))
RotateY(Mathf.DegToRad(-RotationSpeed * dt));
}
private void HandleHeight(float dt)
{
Vector3 pos = GlobalPosition;
if (Input.IsActionPressed("camera_up"))
pos.Y += HeightSpeed * dt;
if (Input.IsActionPressed("camera_down"))
pos.Y -= HeightSpeed * dt;
GlobalPosition = pos;
}
private void UpdateZoom()
{
_camera.Position = new Vector3(0, 0, _zoomDistance);
}
public override void _UnhandledInput(InputEvent @event)
{
if (@event is InputEventMouseButton mouseButton)
{
if (mouseButton.ButtonIndex == MouseButton.WheelUp)
{
_zoomDistance -= ZoomSpeed;
_zoomDistance = Mathf.Clamp(
_zoomDistance,
MinZoom,
MaxZoom
);
UpdateZoom();
}
if (mouseButton.ButtonIndex == MouseButton.WheelDown)
{
_zoomDistance += ZoomSpeed;
_zoomDistance = Mathf.Clamp(
_zoomDistance,
MinZoom,
MaxZoom
);
UpdateZoom();
}
if (mouseButton.ButtonIndex == MouseButton.Middle)
{
_freeLook = mouseButton.Pressed;
}
}
if (_freeLook && @event is InputEventMouseMotion motion)
{
_yawPivot.RotateY(
Mathf.DegToRad(-motion.Relative.X * 0.2f)
);
Vector3 rot = _pitchPivot.Rotation;
rot.X += Mathf.DegToRad(-motion.Relative.Y * 0.2f);
rot.X = Mathf.Clamp(
rot.X,
Mathf.DegToRad(-80),
Mathf.DegToRad(-15)
);
_pitchPivot.Rotation = rot;
}
}
}