rokojori_action_library/Runtime/Interactions/CharacterController/Grounding/Grounding.cs

154 lines
3.3 KiB
C#
Raw Normal View History

2025-12-21 18:56:48 +00:00
using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
[Tool]
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCGroundReset.svg")]
public partial class Grounding:CharacterControllerAction
{
[Export]
public GroundingType groundingType;
bool _grounded = false;
public new bool isGrounded => _hasGroundedOverwrite ? _groundedOverwriteValue : _grounded;
bool _currentlyGrounded = false;
public bool isCurrentlyGrounded => _currentlyGrounded;
[Export]
public Action onGrounded;
[Export]
public Action onUngrounded;
[Export]
public Action onCurrentlyGrounded;
[Export]
public Action onCurrentlyUngrounded;
[Export]
public float keepGroundedDuration = 0.1f;
[ExportGroup( "Velocity Resetting" )]
[Export]
public bool resetVelocityWhenGrounded = true;
bool _hasGroundedOverwrite = false;
bool _groundedOverwriteValue = false;
[ExportGroup( "Debugging")]
[Export]
public bool outputDebugInfo = false;
[Export]
public bool currentlyGrounded = false;
[Export]
public bool grounded = false;
[Export]
public Node groundedCollider;
[Export]
public Node3D groundedPositionTarget;
protected List<CollisionData> _collisionData = CollisionData.ForMaxHits( 1 );
public CollisionData collisionData => _grounded ? null : _collisionData[ 0 ];
float _durationSinceLastGrounded = -1;
CollisionData _lastGroundedCollision = new CollisionData();
public void ApplyUngroundedOverwrite()
{
_hasGroundedOverwrite = true;
_groundedOverwriteValue = false;
}
protected override void _OnTrigger()
{
_hasGroundedOverwrite = false;
var cg = _currentlyGrounded;
var g = _grounded;
_currentlyGrounded = GroundingType.IsGrounded( this, _collisionData );
if ( cg != _currentlyGrounded )
{
if ( _currentlyGrounded )
{
onCurrentlyGrounded?.Trigger();
}
else
{
onCurrentlyUngrounded?.Trigger();
}
}
if ( _currentlyGrounded )
{
_lastGroundedCollision.CopyFrom( _collisionData[ 0 ] );
_durationSinceLastGrounded = 0;
}
_grounded = _currentlyGrounded || _durationSinceLastGrounded < keepGroundedDuration;
if ( g != _grounded )
{
if ( _grounded )
{
onGrounded?.Trigger();
}
else
{
onUngrounded?.Trigger();
}
}
_durationSinceLastGrounded += controller.delta;
if ( outputDebugInfo )
{
currentlyGrounded = _currentlyGrounded;
grounded = _grounded;
groundedCollider = _collisionData[ 0 ].collider;
if ( IsInstanceValid( groundedPositionTarget ) )
{
groundedPositionTarget.GlobalPosition = _lastGroundedCollision.position;
}
}
if ( ! isGrounded || ! resetVelocityWhenGrounded )
{
return;
}
// for ( int i = 0; i < resetBlockers.Length; i++ )
// {
// if ( resetBlockers[ i ].HasActiveForces() )
// {
// return;
// }
// }
SetVelocity( Vector3.Zero );
}
}
}