CharacterController Update
This commit is contained in:
parent
81cf77ce54
commit
f37b4b41c8
|
|
@ -12,6 +12,9 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public CharacterBody3D body;
|
public CharacterBody3D body;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Grounding grounding;
|
||||||
|
|
||||||
public enum CharacterUpdateMode
|
public enum CharacterUpdateMode
|
||||||
{
|
{
|
||||||
Process,
|
Process,
|
||||||
|
|
@ -39,10 +42,17 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public float lastGroundedHeight = 0;
|
public float lastGroundedHeight = 0;
|
||||||
|
|
||||||
|
|
||||||
public float delta = 0;
|
public float delta = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public bool isGrounded
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return grounding == null ? body.IsOnFloor() : grounding.isGrounded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void _Process( double delta )
|
public override void _Process( double delta )
|
||||||
{
|
{
|
||||||
if ( Engine.IsEditorHint() && graphics == null || body == null )
|
if ( Engine.IsEditorHint() && graphics == null || body == null )
|
||||||
|
|
@ -55,7 +65,7 @@ namespace Rokojori
|
||||||
ProcessActions( (float) delta );
|
ProcessActions( (float) delta );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( body.IsOnFloor() )
|
if ( isGrounded )
|
||||||
{
|
{
|
||||||
lastGroundedHeight = graphics.GlobalPosition.Y;
|
lastGroundedHeight = graphics.GlobalPosition.Y;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,16 +21,39 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public SceneCondition sceneCondition;
|
public SceneCondition sceneCondition;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public CharacterControllerAction[] blockers = [];
|
||||||
|
|
||||||
|
public bool isGrounded => _controller.isGrounded;
|
||||||
|
|
||||||
public void SetCharacterController( CharacterController cc )
|
public void SetCharacterController( CharacterController cc )
|
||||||
{
|
{
|
||||||
_controller = cc;
|
_controller = cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool HasActiveForces()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public CharacterBody3D body => controller.body;
|
public CharacterBody3D body => controller.body;
|
||||||
|
|
||||||
|
public bool blockersActive
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return blockers != null && blockers.Has( b => b.HasActiveForces() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void AddVelocity( Vector3 velocity, float delta = -1 )
|
public void AddVelocity( Vector3 velocity, float delta = -1 )
|
||||||
{
|
{
|
||||||
|
if ( blockersActive )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
delta = delta < 0 ? controller.delta : delta;
|
delta = delta < 0 ? controller.delta : delta;
|
||||||
|
|
||||||
body.Velocity += velocity * delta;
|
body.Velocity += velocity * delta;
|
||||||
|
|
@ -38,11 +61,21 @@ namespace Rokojori
|
||||||
|
|
||||||
public void SetScaledVelocity( float scale )
|
public void SetScaledVelocity( float scale )
|
||||||
{
|
{
|
||||||
|
if ( blockersActive )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
body.Velocity *= scale;
|
body.Velocity *= scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVelocity( Vector3 velocity, float delta = -1 )
|
public void SetVelocity( Vector3 velocity, float delta = -1 )
|
||||||
{
|
{
|
||||||
|
if ( blockersActive )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
delta = delta < 0 ? controller.delta : delta;
|
delta = delta < 0 ? controller.delta : delta;
|
||||||
body.Velocity = velocity * delta;
|
body.Velocity = velocity * delta;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ namespace Rokojori
|
||||||
|
|
||||||
protected override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
var onFloor = body.IsOnFloor();
|
var onFloor = isGrounded;
|
||||||
_onFloor = onFloor;
|
_onFloor = onFloor;
|
||||||
|
|
||||||
characterMovementData.Reset( this );
|
characterMovementData.Reset( this );
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,24 @@ namespace Rokojori
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCGravity.svg")]
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCGravity.svg")]
|
||||||
public partial class Gravity:CharacterControllerAction
|
public partial class Gravity:CharacterControllerAction
|
||||||
{
|
{
|
||||||
|
public static readonly float EarthGravity = 9.80665f;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float strength = 10;
|
public GravityStrength strength;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public GravityStrength fallingStrength;
|
||||||
|
|
||||||
protected override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( body.IsOnFloor() )
|
if ( isGrounded || strength == null )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// RJLog.Log( controller.body.Velocity );
|
|
||||||
AddVelocity( Vector3.Down * strength );
|
var strengthSource = body.Velocity.Y > 0 || fallingStrength == null ? strength : fallingStrength;
|
||||||
|
|
||||||
|
AddVelocity( Vector3.Down * strengthSource.GetGravityStrength( this ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public partial class EarthGravityStrength:GravityStrength
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public float multiply = 1f;
|
||||||
|
|
||||||
|
public override float GetGravityStrength( Gravity gravity )
|
||||||
|
{
|
||||||
|
return Gravity.EarthGravity * multiply;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dug045ws8o2fy
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public abstract partial class GravityStrength:Resource
|
||||||
|
{
|
||||||
|
public abstract float GetGravityStrength( Gravity gravity );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bey6k6vokedqx
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public partial class HeightDurationGravityStrength:GravityStrength
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public HeightDuration heightDuration;
|
||||||
|
|
||||||
|
public override float GetGravityStrength( Gravity gravity )
|
||||||
|
{
|
||||||
|
return heightDuration.height * 2f / ( heightDuration.duration * heightDuration.duration );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://c0qpyxi2615lf
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public partial class RawGravityStrength:GravityStrength
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public float strength = Gravity.EarthGravity;
|
||||||
|
|
||||||
|
public override float GetGravityStrength( Gravity gravity )
|
||||||
|
{
|
||||||
|
return strength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cgg7rx8nnpqv5
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public partial class ReferencedGravityStrength:GravityStrength
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public GravityStrength referencedStrength;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float multiplier = 1f;
|
||||||
|
|
||||||
|
public override float GetGravityStrength( Gravity gravity )
|
||||||
|
{
|
||||||
|
return multiplier * referencedStrength.GetGravityStrength( gravity );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://qstgyis6jyd6
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
protected override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( ! body.IsOnFloor() )
|
if ( ! isGrounded )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
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 DownGroundingType:GroundingType
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public float downLength = 0.3f;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float upOffset = 0f;
|
||||||
|
|
||||||
|
|
||||||
|
protected override bool _IsGrounded( Grounding grounding, List<CollisionData> collisionData )
|
||||||
|
{
|
||||||
|
var position = grounding.body.GlobalPosition;
|
||||||
|
var from = position + upOffset * Vector3.Up;
|
||||||
|
var to = from + Vector3.Down * downLength;
|
||||||
|
|
||||||
|
var hits = PhysicsRayCast.GetAll( collisionData, grounding.body, from, to );
|
||||||
|
|
||||||
|
if ( hits == 0 )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bs6oahk3jrjcq
|
||||||
|
|
@ -0,0 +1,154 @@
|
||||||
|
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 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://b6stp3kea0qo8
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
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 abstract partial class GroundingType:Resource
|
||||||
|
{
|
||||||
|
protected abstract bool _IsGrounded( Grounding grounding, List<CollisionData> collisionData );
|
||||||
|
|
||||||
|
public static bool IsGrounded( Grounding grounding, List<CollisionData> collisionData )
|
||||||
|
{
|
||||||
|
if ( grounding == null )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( grounding.groundingType == null )
|
||||||
|
{
|
||||||
|
var grounded = grounding.body.IsOnFloor();
|
||||||
|
|
||||||
|
if ( grounded )
|
||||||
|
{
|
||||||
|
collisionData[ 0 ].CopyFrom( grounding.body.GetLastSlideCollision() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return grounded;
|
||||||
|
}
|
||||||
|
|
||||||
|
return grounding.groundingType._IsGrounded( grounding, collisionData );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://hrrp2b8esaws
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public partial class HeightDuration:Resource
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public float height = 1;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float duration = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://0ao3381pywpg
|
||||||
|
|
@ -15,28 +15,51 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public Action onJump;
|
public Action onJump;
|
||||||
|
|
||||||
[ExportGroup( "Jump Impulse")]
|
[ExportGroup( "Jumping")]
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float jumpImpulseStrength;
|
public JumpStrength strength;
|
||||||
|
[Export]
|
||||||
|
public float minJumpDuration = 0.5f;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Gravity gravity;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[ExportGroup( "Movement")]
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float forwardStrength = 0;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float rightStrength = 0;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public CharacterMovement movement;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "0,5" )]
|
||||||
|
public float movementToJumpDirection = 0.5f;
|
||||||
|
|
||||||
[Export( PropertyHint.Range, "0,100" )]
|
[Export( PropertyHint.Range, "0,100" )]
|
||||||
public float velocityToJumpDirection = 0.5f;
|
public float movementDirectionToFixedJumpDirection = 0.5f;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float velocityTresholdForJumpDirection = 1f;
|
public float movementTresholdForJumpDirection = 1f;
|
||||||
|
|
||||||
|
|
||||||
[ExportGroup( "Air Control")]
|
[ExportGroup( "Air Control")]
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public GravityStrength airControlGravityStrength;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float maxAirControlDuration;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Curve airControlCurveStrength = MathX.Curve( 1, 0 );
|
public Curve airControlCurveStrength = MathX.Curve( 1, 0 );
|
||||||
|
|
||||||
[Export]
|
|
||||||
public float airMaxControlStrength;
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public float maxAirControlDuration;
|
|
||||||
|
|
||||||
float jumpedDuration;
|
float jumpedDuration;
|
||||||
|
|
||||||
|
|
@ -46,91 +69,109 @@ namespace Rokojori
|
||||||
|
|
||||||
bool needsToRelease = false;
|
bool needsToRelease = false;
|
||||||
|
|
||||||
bool inAir = false;
|
bool jumping = false;
|
||||||
float airStart = 0;
|
float jumpStart = 0;
|
||||||
|
|
||||||
|
Vector3 jumpDirection;
|
||||||
|
|
||||||
|
public override bool HasActiveForces()
|
||||||
|
{
|
||||||
|
return jumping;
|
||||||
|
}
|
||||||
|
|
||||||
public bool IsJumping()
|
public bool IsJumping()
|
||||||
{
|
{
|
||||||
return inAir;
|
return jumping;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetAirTime()
|
public float GetJumpStartTime()
|
||||||
{
|
{
|
||||||
return airStart == -1 ? 0 : ( TimeLine.osTime - airStart );
|
return jumpStart == -1 ? 0 : ( TimeLine.osTime - jumpStart );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( body.IsOnFloor() )
|
if ( ! jumping && isGrounded && button.isDown )
|
||||||
{
|
{
|
||||||
if ( inAir )
|
_StartJump();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( jumping )
|
||||||
|
{
|
||||||
|
_OnJumping();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void _StartJump()
|
||||||
|
{
|
||||||
|
// jumpPressing = true;
|
||||||
|
jumpedDuration = 0;
|
||||||
|
jumping = true;
|
||||||
|
jumpStart = TimeLine.osTime;
|
||||||
|
|
||||||
|
Trigger( onJump );
|
||||||
|
|
||||||
|
jumpDirection = Vector3.Up * strength.GetJumpStrength( this );
|
||||||
|
|
||||||
|
if ( movement != null )
|
||||||
|
{
|
||||||
|
var currentMovement = movement.smoothedMovement * controller.delta;
|
||||||
|
this.LogInfo( body.Velocity, currentMovement );
|
||||||
|
|
||||||
|
if ( currentMovement.Length() > movementTresholdForJumpDirection )
|
||||||
{
|
{
|
||||||
inAir = false;
|
var xz = currentMovement;
|
||||||
airStart = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( jumpPressing )
|
|
||||||
{
|
|
||||||
jumpPressing = false;
|
|
||||||
needsToRelease = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! ( jumpPressing || body.IsOnFloor() ) )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! button.isActive )
|
|
||||||
{
|
|
||||||
jumpPressing = false;
|
|
||||||
needsToRelease = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( needsToRelease )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! jumpPressing )
|
|
||||||
{
|
|
||||||
jumpPressing = true;
|
|
||||||
jumpedDuration = 0;
|
|
||||||
inAir = true;
|
|
||||||
airStart = TimeLine.osTime;
|
|
||||||
|
|
||||||
Trigger( onJump );
|
|
||||||
|
|
||||||
var jumpDirection = Vector3.Up * jumpImpulseStrength;
|
|
||||||
|
|
||||||
if ( body.Velocity.Length() > velocityTresholdForJumpDirection )
|
|
||||||
{
|
|
||||||
var xz = body.Velocity;
|
|
||||||
xz.Y = 0;
|
xz.Y = 0;
|
||||||
// xz = xz.Normalized();
|
|
||||||
|
|
||||||
jumpDirection += xz * velocityToJumpDirection;
|
jumpDirection += xz * movementToJumpDirection + xz.Normalized() * movementDirectionToFixedJumpDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetVelocity( jumpDirection );
|
}
|
||||||
|
|
||||||
return;
|
jumpDirection += body.GlobalForward() * forwardStrength;
|
||||||
|
jumpDirection += body.GlobalRight() * rightStrength;
|
||||||
|
|
||||||
|
SetVelocity( jumpDirection, 1 );
|
||||||
|
this.LogInfo( jumpDirection );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void _OnJumping()
|
||||||
|
{
|
||||||
|
if ( jumping && jumpedDuration < minJumpDuration )
|
||||||
|
{
|
||||||
|
if ( controller.grounding != null )
|
||||||
|
{
|
||||||
|
controller.grounding.ApplyUngroundedOverwrite();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( airControlGravityStrength != null && gravity != null && button.isHold &&
|
||||||
|
jumpedDuration < maxAirControlDuration
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var gravityStrength = airControlGravityStrength.GetGravityStrength( gravity );
|
||||||
|
var gravityStrengthMultiply = 1f;
|
||||||
|
|
||||||
|
if ( airControlCurveStrength != null )
|
||||||
|
{
|
||||||
|
gravityStrengthMultiply = airControlCurveStrength.Sample( jumpedDuration / maxAirControlDuration );
|
||||||
|
}
|
||||||
|
|
||||||
|
AddVelocity( gravityStrength * Vector3.Up * gravityStrengthMultiply );
|
||||||
}
|
}
|
||||||
|
|
||||||
jumpedDuration += controller.delta;
|
jumpedDuration += controller.delta;
|
||||||
|
|
||||||
canJump = jumpedDuration < maxAirControlDuration;
|
if ( jumpedDuration > minJumpDuration )
|
||||||
|
|
||||||
|
|
||||||
if ( canJump )
|
|
||||||
{
|
{
|
||||||
var jumpStrengthMultiply = airControlCurveStrength.Sample( jumpedDuration / maxAirControlDuration );
|
jumping = false;
|
||||||
AddVelocity( Vector3.Up * airMaxControlStrength * jumpStrengthMultiply );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public partial class HeightBasedJumpStrength:JumpStrength
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public float height = 1;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float airControlAmount = 1f;
|
||||||
|
|
||||||
|
public override float GetJumpStrength( Jump jump )
|
||||||
|
{
|
||||||
|
var gravityStrength = jump.gravity == null ? Gravity.EarthGravity :
|
||||||
|
jump.gravity.strength.GetGravityStrength( jump.gravity );
|
||||||
|
|
||||||
|
if ( airControlAmount > 0f )
|
||||||
|
{
|
||||||
|
var airGravityStrength = jump.airControlGravityStrength.GetGravityStrength( jump.gravity ) * 0.5f;
|
||||||
|
|
||||||
|
gravityStrength -= airGravityStrength * airControlAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Mathf.Sqrt( 2f * gravityStrength * height );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dpqn3p0013myo
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public partial class HeightDurationJumpStrength:JumpStrength
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public HeightDuration heightDuration;
|
||||||
|
|
||||||
|
public override float GetJumpStrength( Jump jump )
|
||||||
|
{
|
||||||
|
return heightDuration.height * 2f / heightDuration.duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dtgxngdobln4x
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public partial class HumanJumpStrength:JumpStrength
|
||||||
|
{
|
||||||
|
public static readonly float HumanAverageStrength = 3;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float humanPowerMultiply = 1f;
|
||||||
|
|
||||||
|
public override float GetJumpStrength( Jump jump )
|
||||||
|
{
|
||||||
|
return HumanJumpStrength.HumanAverageStrength * humanPowerMultiply;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bp4v0yyavxvxc
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public abstract partial class JumpStrength:Resource
|
||||||
|
{
|
||||||
|
public abstract float GetJumpStrength( Jump jump );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://c3t2qjq71h4gb
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCJump.svg")]
|
||||||
|
public partial class RawJumpStrength:JumpStrength
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public float jumpImpulseStrength = 200;
|
||||||
|
|
||||||
|
[ExportGroup( "Debug Info")]
|
||||||
|
[ExportToolButton( "Compute Height")]
|
||||||
|
public Callable computeHeightButton => Callable.From(
|
||||||
|
( )=>
|
||||||
|
{
|
||||||
|
var y = 0f;
|
||||||
|
var v = jumpImpulseStrength;
|
||||||
|
var gravity = Gravity.EarthGravity;
|
||||||
|
var timeStep = 1f/60f;
|
||||||
|
var maxY = y;
|
||||||
|
var zeroTime = 0f;
|
||||||
|
var maxTime = -1f;
|
||||||
|
|
||||||
|
while ( y >= 0 )
|
||||||
|
{
|
||||||
|
v -= gravity * timeStep;;
|
||||||
|
y += v * timeStep;
|
||||||
|
|
||||||
|
if ( y > maxY )
|
||||||
|
{
|
||||||
|
maxY = Mathf.Max( y, maxY );
|
||||||
|
maxTime = zeroTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
zeroTime += timeStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.LogInfo( "MaxY:", maxY, "Max Time:", maxTime, "Zero Time:", zeroTime );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
public override float GetJumpStrength( Jump jump )
|
||||||
|
{
|
||||||
|
return jumpImpulseStrength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://c3uursukaal3n
|
||||||
|
|
@ -16,6 +16,61 @@ namespace Rokojori
|
||||||
public Rid rid;
|
public Rid rid;
|
||||||
|
|
||||||
|
|
||||||
|
public void CopyFrom( KinematicCollision3D kinematicCollision3D, int collisionIndex = 0 )
|
||||||
|
{
|
||||||
|
if ( kinematicCollision3D.GetCollisionCount() <= collisionIndex )
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasCollision = true;
|
||||||
|
position = kinematicCollision3D.GetPosition();
|
||||||
|
normal = kinematicCollision3D.GetNormal();
|
||||||
|
collider = (Node) kinematicCollision3D.GetCollider( collisionIndex );
|
||||||
|
rid = (Rid) kinematicCollision3D.GetColliderRid( collisionIndex );
|
||||||
|
shape = (Shape3D) kinematicCollision3D.GetColliderShape( collisionIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
hasCollision = false;
|
||||||
|
|
||||||
|
position = Vector3.Zero;
|
||||||
|
normal = Vector3.Up;
|
||||||
|
collider = null;
|
||||||
|
rid = new Rid();
|
||||||
|
shape = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CopyFrom( CollisionData collisionData )
|
||||||
|
{
|
||||||
|
if ( ! collisionData.hasCollision )
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasCollision = true;
|
||||||
|
position = collisionData.position;
|
||||||
|
normal = collisionData.normal;
|
||||||
|
collider = collisionData.collider;
|
||||||
|
rid = collisionData.rid;
|
||||||
|
shape = collisionData.shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<CollisionData> ForMaxHits( int maxHits )
|
||||||
|
{
|
||||||
|
var data = new List<CollisionData>();
|
||||||
|
|
||||||
|
for ( int i = 0; i < maxHits; i++ )
|
||||||
|
{
|
||||||
|
data.Add( new CollisionData() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
public static bool HasCollisionMask( Node n )
|
public static bool HasCollisionMask( Node n )
|
||||||
{
|
{
|
||||||
return n is CsgShape3D || n is CollisionObject3D;
|
return n is CsgShape3D || n is CollisionObject3D;
|
||||||
|
|
@ -85,7 +140,7 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
var physics = world.DirectSpaceState;
|
var physics = world.DirectSpaceState;
|
||||||
|
|
||||||
var excludes = new Array<Rid>();
|
var excludes = rayParameters.Exclude;
|
||||||
|
|
||||||
var maxHits = 10000;
|
var maxHits = 10000;
|
||||||
|
|
||||||
|
|
@ -118,7 +173,7 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
var physics = world.DirectSpaceState;
|
var physics = world.DirectSpaceState;
|
||||||
|
|
||||||
var excludes = new Array<Rid>();
|
var excludes = rayParameters.Exclude;
|
||||||
|
|
||||||
var numCollisions = 0;
|
var numCollisions = 0;
|
||||||
|
|
||||||
|
|
@ -147,7 +202,7 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
var physics = world.DirectSpaceState;
|
var physics = world.DirectSpaceState;
|
||||||
|
|
||||||
var excludes = new Array<Rid>();
|
var excludes = rayParameters.Exclude;
|
||||||
|
|
||||||
var collisions = new List<CollisionData>();
|
var collisions = new List<CollisionData>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class PhysicsRayCast
|
||||||
|
{
|
||||||
|
public static CollisionData GetFirst( CharacterBody3D body, Vector3 from, Vector3 to )
|
||||||
|
{
|
||||||
|
var world = body.GetWorld3D();
|
||||||
|
var rayParameters = new PhysicsRayQueryParameters3D
|
||||||
|
{
|
||||||
|
From = from,
|
||||||
|
To = to,
|
||||||
|
CollisionMask = body.CollisionMask,
|
||||||
|
CollideWithAreas = false,
|
||||||
|
CollideWithBodies = true
|
||||||
|
};
|
||||||
|
|
||||||
|
rayParameters.Exclude = [ body.GetRid() ];
|
||||||
|
var hits = CollisionData.MultiRayCast( world, rayParameters, 1 );
|
||||||
|
|
||||||
|
return hits.Count == 0 ? null : hits[ 0 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CollisionData GetFirst( CharacterBody3D body, Vector3 direction )
|
||||||
|
{
|
||||||
|
var from = body.GlobalPosition;
|
||||||
|
var to = from + direction;
|
||||||
|
|
||||||
|
return GetFirst( body, from, to );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetAll( List<CollisionData> outputCollisionData, CharacterBody3D body, Vector3 from, Vector3 to )
|
||||||
|
{
|
||||||
|
var world = body.GetWorld3D();
|
||||||
|
var rayParameters = new PhysicsRayQueryParameters3D
|
||||||
|
{
|
||||||
|
From = from,
|
||||||
|
To = to,
|
||||||
|
CollisionMask = body.CollisionMask,
|
||||||
|
CollideWithAreas = false,
|
||||||
|
CollideWithBodies = true
|
||||||
|
};
|
||||||
|
|
||||||
|
rayParameters.Exclude = [ body.GetRid() ];
|
||||||
|
return CollisionData.MultiRayCast( world, rayParameters, outputCollisionData );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetAll( List<CollisionData> outputCollisionData, CharacterBody3D body, Vector3 direction )
|
||||||
|
{
|
||||||
|
var from = body.GlobalPosition;
|
||||||
|
var to = from + direction;
|
||||||
|
|
||||||
|
return GetAll( outputCollisionData, body, from, to );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cu5o06n50gy8g
|
||||||
|
|
@ -138,7 +138,7 @@ namespace Rokojori
|
||||||
|
|
||||||
hasDevice = true;
|
hasDevice = true;
|
||||||
|
|
||||||
this.LogInfo( "Device Type Change:", lastActiveDevice.GetInfo() );
|
// this.LogInfo( "Device Type Change:", lastActiveDevice.GetInfo() );
|
||||||
|
|
||||||
if ( confineMouse && DefaultSensorDeviceSelector.IsMouseDevice( lastActiveDevice ) )
|
if ( confineMouse && DefaultSensorDeviceSelector.IsMouseDevice( lastActiveDevice ) )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 45 MiB After Width: | Height: | Size: 53 MiB |
Loading…
Reference in New Issue