rokojori_action_library/Runtime/Behavior/CharacterBodyBehaviorMoveme...

100 lines
1.9 KiB
C#

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 );
}
}