using System; using Godot; namespace BITKit; public partial class FreeLookCamera : Node3D,IVirtualCamera { [Export] private int fov; [Export] private bool isEnabled; [Export] private Curve wheelCurve; [Export(PropertyHint.Range,"0.32,8")] private float distance; [Export] private float maxDistance; private Vector3 rotation; private Vector3 position; void IActivable.SetActive(bool active) => isEnabled = active; int IVirtualCamera.FOV => fov; bool IVirtualCamera.IsEnabled => isEnabled; // ReSharper disable once ConvertToAutoProperty Vector3 IVirtualCamera.Rotation =>rotation ; // ReSharper disable once ConvertToAutoProperty Vector3 IVirtualCamera.Position => position; private Vector3 euler; private bool isMoving; public override void _Ready() { euler = Rotation; position = Position; CameraService.Register(this); } protected override void Dispose(bool disposing) { CameraService.UnRegister(this); } public override void _Process(double delta) { var _rot = Quaternion.FromEuler(euler); var _dir = _rot * Vector3.Forward * distance; var newPos = Position - _dir; position = position.Lerp(newPos, 1); rotation = rotation.Lerp(euler, 1); BITAppForGodot.AllowCursor.SetDisableElements(this,Input.IsMouseButtonPressed(MouseButton.Middle)); isMoving = Input.IsKeyPressed(Key.Shift); SetMeta("CurrentRot",_rot); } public override void _Input(InputEvent @event) { switch (@event) { case InputEventMouseMotion mouseMotion: if(Input.IsMouseButtonPressed(MouseButton.Middle) is false)break; if (isMoving) { var velocity = mouseMotion.Relative; Position += Quaternion.FromEuler(euler) * new Vector3() { X= -velocity.X, Y = velocity.Y } * (float)GetProcessDeltaTime(); } else { var mouseVelocity = mouseMotion.Relative /* 0.022f*/ * 1.81f * (float)GetProcessDeltaTime(); euler.X -= mouseVelocity.Y; euler.Y -= mouseVelocity.X; euler.Y %= 360; euler.X = Math.Clamp(euler.X, -80, 80); } break; case InputEventMouseButton mouseButton: var delta =(float) GetProcessDeltaTime() * (wheelCurve?.Sample(distance*0.1f) ?? 32); switch (mouseButton.ButtonIndex) { case MouseButton.WheelUp: distance -= delta; break; case MouseButton.WheelDown: distance += delta; break; } distance = Math.Clamp(distance,0, maxDistance); break; } } }