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("YawPivot"); // _pitchPivot = _yawPivot.GetNode("PitchPivot"); // _camera = _pitchPivot.GetNode("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; } } }