using Godot; using Movementtests.interfaces; namespace Movementtests.scenes.movement; public partial class CFlyingMovement : Node3D, IMoveable { [Export] public RMovement RMovement { get; set; } [Export(PropertyHint.Layers3DPhysics)] public uint TerrainCollision { get; set; } = 1; private bool _movingToDesiredHeight = true; private Vector3 _randomDirection; public override void _Ready() { _randomDirection = new Vector3(GD.RandRange(-1, 1), 1, GD.RandRange(-1, 1)).Normalized(); } public Vector3 ComputeVelocity(MovementInputs inputs) { var velocity = inputs.Velocity; var spaceState = GetWorld3D().DirectSpaceState; var target = inputs.TargetLocation; var direction = (target - GlobalPosition).Normalized(); // Check if we have a direct line of sight to the player if (!_movingToDesiredHeight) { velocity = velocity.Lerp(direction * RMovement.Speed, (float) inputs.delta * RMovement.Acceleration); var query = PhysicsRayQueryParameters3D.Create(GlobalPosition, target, TerrainCollision); var result = spaceState.IntersectRay(query); if (result.Count > 0) { _movingToDesiredHeight = true; _randomDirection = new Vector3(GD.RandRange(-1, 1), 1, GD.RandRange(-1, 1)).Normalized(); } } else { velocity = velocity.Lerp(_randomDirection * RMovement.Speed, (float) inputs.delta * RMovement.Acceleration); var groundQuery = PhysicsRayQueryParameters3D.Create(GlobalPosition, GlobalPosition+Vector3.Down*RMovement.TargetHeight, TerrainCollision); var groundResult = spaceState.IntersectRay(groundQuery); if (groundResult.Count == 0) { velocity.Y = 0; var query = PhysicsRayQueryParameters3D.Create(GlobalPosition, target, TerrainCollision); var result = spaceState.IntersectRay(query); if (result.Count == 0) { _movingToDesiredHeight = false; } } } return velocity; } }