using System; using System.Diagnostics; 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; [Export] private StringResource stringResource; 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 eulur; private bool isMoving; public override void _Ready() { eulur = 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(eulur); var _dir = _rot * Vector3.Forward * distance; var newPos = Position - _dir; position = position.Lerp(newPos, 1); rotation = rotation.Lerp(eulur, 1); BITAppForGodot.AllowCursor.SetDisableElements(this,Input.IsMouseButtonPressed(MouseButton.Middle)); isMoving = Input.IsKeyPressed(Key.Shift); } 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(eulur) * new Vector3() { X= -velocity.X, Y = velocity.Y } * (float)GetProcessDeltaTime(); } else { var mouseVelocity = mouseMotion.Relative /* 0.022f*/ * 1.81f * (float)GetProcessDeltaTime(); eulur.X -= mouseVelocity.Y; eulur.Y -= mouseVelocity.X; eulur.Y %= 360; eulur.X = Math.Clamp(eulur.X, -80, 80); } break; case InputEventMouseButton mouseButton: var delta =(float) GetProcessDeltaTime() * wheelCurve.Sample(distance*0.1f); switch (mouseButton.ButtonIndex) { case MouseButton.WheelUp: distance -= delta; break; case MouseButton.WheelDown: distance += delta; break; default: break; } distance = Math.Clamp(distance,0, maxDistance); break; } } }