80 lines
2.0 KiB
C#
80 lines
2.0 KiB
C#
using Godot;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Godot.Collections;
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/CCMoveAndSlide.svg")]
|
|
public partial class MoveAndSlide:CharacterControllerAction
|
|
{
|
|
[Export]
|
|
public bool useStepping = false;
|
|
|
|
[Export]
|
|
public float stepMaxHeight = 0.2f;
|
|
|
|
protected override void _OnTrigger()
|
|
{
|
|
var body = controller.body;
|
|
var motion = controller.body.Velocity * controller.delta;
|
|
|
|
var collision = body.MoveAndCollide( motion, testOnly: true );
|
|
|
|
if ( collision != null && StepUp( motion ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
controller.body.MoveAndSlide();
|
|
}
|
|
|
|
protected bool StepUp( Vector3 motion )
|
|
{
|
|
var up = Vector3.Up * stepMaxHeight;
|
|
|
|
var hitAbove = controller.body.TestMove( controller.body.GlobalTransform, up );
|
|
|
|
if ( hitAbove )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool hitForward = controller.body.TestMove( controller.body.GlobalTransform.Translated( up ), motion );
|
|
|
|
if ( ! hitForward )
|
|
{
|
|
var space = controller.body.GetWorld3D().DirectSpaceState;
|
|
var origin = controller.body.GlobalPosition;
|
|
var stepUpOrigin = controller.body.GlobalPosition + up;
|
|
|
|
var downHit = space.IntersectRay(
|
|
new PhysicsRayQueryParameters3D
|
|
{
|
|
From = stepUpOrigin,
|
|
To = stepUpOrigin + Vector3.Down * ( stepMaxHeight + 0.1f ),
|
|
CollisionMask = 1,
|
|
CollideWithAreas = false,
|
|
CollideWithBodies = true
|
|
}
|
|
);
|
|
|
|
if ( downHit.Count == 0 )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
var exactStepAmount = downHit[ "position" ].AsVector3().Y - origin.Y;
|
|
|
|
if ( exactStepAmount > 0 && exactStepAmount <= stepMaxHeight )
|
|
{
|
|
controller.body.GlobalTranslate( new Vector3( 0, exactStepAmount, 0 ) );
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
} |