using Godot; using Rokojori.Extensions; namespace Rokojori; [Tool] [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Action.svg")] public partial class CharacterBodyBehaviorMovement:BehaviorMovement { [Export] public CharacterBody3D body; [Export] public float moveSpeed = 5f; [Export] public float arrivalDistance = 0.1f; Node3D _followTarget; Vector3? _targetPosition; public override void GoToPosition( Vector3 worldPosition ) { _followTarget = null; _targetPosition = worldPosition; } public override void LookAtPosition( Vector3 worldPosition ) { if ( body == null ) { return; } var direction = worldPosition - body.GlobalPosition; direction.Y = 0; if ( direction.LengthSquared() < 0.0001f ) { return; } body.GlobalTransform = new Transform3D( Basis.LookingAt( direction, Vector3.Up ), body.GlobalPosition ); } public override void GoTo( Node3D node ) { _followTarget = null; _targetPosition = node == null ? null : node.GlobalPosition; } public override void Follow( Node3D node ) { _followTarget = node; _targetPosition = null; } public override void LookAt( Node3D node ) { if ( node == null ) { return; } LookAtPosition( node.GlobalPosition ); } public override void _PhysicsProcess( double delta ) { if ( body == null ) { return; } Vector3? target = _followTarget != null ? _followTarget.GlobalPosition : _targetPosition; if ( target == null ) { return; } var toTarget = target.Value - body.GlobalPosition; toTarget.Y = 0; if ( toTarget.Length() <= arrivalDistance ) { body.Velocity = Vector3.Zero; body.MoveAndSlide(); return; } var direction = toTarget.Normalized(); body.Velocity = direction * moveSpeed; body.MoveAndSlide(); LookAtPosition( body.GlobalPosition + direction ); } }