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