2022-12-31 18:36:52 +01:00
|
|
|
using Godot;
|
2022-12-28 21:57:34 +01:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// </summary>
|
2023-02-12 16:30:56 +01:00
|
|
|
public class GroundMotionComponent : Component
|
2022-12-28 21:57:34 +01:00
|
|
|
{
|
2022-12-31 18:36:52 +01:00
|
|
|
public float Accel = 50;
|
|
|
|
public float Damping = 0.2f;
|
2023-11-10 11:11:08 +01:00
|
|
|
public Vector3 DirectionToTarget = Vector3.Zero;
|
|
|
|
public float DistanceToTarget;
|
2023-01-03 17:46:55 +01:00
|
|
|
public float MaxSpeed = 8;
|
2023-11-10 11:11:08 +01:00
|
|
|
|
2023-02-12 16:30:56 +01:00
|
|
|
public float RotationSpeedRadPerSecond = 270 * Mathf.Pi / 180;
|
2023-11-10 11:11:08 +01:00
|
|
|
public float TargetAngle;
|
|
|
|
public float TargetDeltaAngle;
|
|
|
|
|
2023-11-10 12:22:17 +01:00
|
|
|
private void CalcAndApplyOrientation(float delta, Entity entity, Vector3 targetPosition, float targetAngle)
|
2023-10-27 23:00:54 +02:00
|
|
|
{
|
|
|
|
float deltaAngleAbsolute = Mathf.Abs(TargetDeltaAngle);
|
|
|
|
if (deltaAngleAbsolute > 0.001)
|
|
|
|
{
|
2023-11-10 11:11:08 +01:00
|
|
|
if (RotationSpeedRadPerSecond * delta >= deltaAngleAbsolute)
|
2023-10-27 23:00:54 +02:00
|
|
|
{
|
|
|
|
entity.PlaneAngle = TargetAngle;
|
|
|
|
TargetDeltaAngle = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
entity.PlaneAngle += Mathf.Sign(TargetDeltaAngle) * RotationSpeedRadPerSecond * delta;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TargetDeltaAngle = 0;
|
|
|
|
}
|
|
|
|
}
|
2023-11-10 11:11:08 +01:00
|
|
|
|
2023-01-03 17:46:55 +01:00
|
|
|
private void CalcPlaneVelocity(float delta, Entity entity, Vector3 targetPosition)
|
2022-12-28 21:57:34 +01:00
|
|
|
{
|
2023-10-27 23:00:54 +02:00
|
|
|
Vector2 planeTargetDirection = new Vector2(DirectionToTarget.x, DirectionToTarget.z);
|
2023-11-10 11:11:08 +01:00
|
|
|
|
2023-01-03 17:46:55 +01:00
|
|
|
Vector2 planeVelocity = new Vector2(entity.Velocity.x, entity.Velocity.z);
|
|
|
|
// GD.Print("-- Step: distance: " + targetDistance + " dir: " + planeTargetDirection + " speed: " + planeVelocity.Length() + " vel dir: " + planeVelocity.Normalized());
|
|
|
|
planeVelocity -= planeVelocity * Damping;
|
|
|
|
// GD.Print(" damp : speed: " + planeVelocity.Length() + " vel dir: " + planeVelocity.Normalized());
|
2023-11-10 11:11:08 +01:00
|
|
|
|
2023-10-27 23:00:54 +02:00
|
|
|
if (DistanceToTarget < 0.01)
|
2022-12-28 21:57:34 +01:00
|
|
|
{
|
2023-01-03 17:46:55 +01:00
|
|
|
planeVelocity = Vector2.Zero;
|
2023-11-10 11:11:08 +01:00
|
|
|
}
|
|
|
|
else if (TargetDeltaAngle == 0.0)
|
|
|
|
{
|
2023-01-03 17:46:55 +01:00
|
|
|
planeVelocity = planeVelocity.Length() * planeTargetDirection + planeTargetDirection * Accel * delta;
|
|
|
|
// GD.Print(" accel: speed: " + planeVelocity.Length() + " vel dir: " + planeVelocity.Normalized());
|
2022-12-31 18:36:52 +01:00
|
|
|
|
2023-11-10 11:11:08 +01:00
|
|
|
var projectedStep = planeTargetDirection.Dot(planeVelocity * delta);
|
2023-01-03 17:46:55 +01:00
|
|
|
// GD.Print(" Projected step: " + projectedStep + " Speed: " + planeVelocity.Length() + " delta: " + delta);
|
2023-10-27 23:00:54 +02:00
|
|
|
if (projectedStep > DistanceToTarget)
|
2022-12-31 18:36:52 +01:00
|
|
|
{
|
2023-10-27 23:00:54 +02:00
|
|
|
planeVelocity *= DistanceToTarget / projectedStep;
|
2023-01-03 17:46:55 +01:00
|
|
|
projectedStep = planeTargetDirection.Dot(planeVelocity * delta);
|
|
|
|
// GD.Print(" corr speed: " + planeVelocity.Length() + " step: " + projectedStep);
|
2022-12-31 18:36:52 +01:00
|
|
|
}
|
2023-11-10 11:11:08 +01:00
|
|
|
|
|
|
|
var planeSpeed = planeVelocity.Length();
|
|
|
|
if (planeSpeed > MaxSpeed) planeVelocity *= MaxSpeed / planeSpeed;
|
2023-01-03 17:46:55 +01:00
|
|
|
}
|
2023-10-27 23:00:54 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
planeVelocity = Vector2.Zero;
|
|
|
|
}
|
2023-01-03 17:46:55 +01:00
|
|
|
|
|
|
|
entity.Velocity = new Vector3(planeVelocity.x, entity.Velocity.y, planeVelocity.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void CalcVerticalVelocity(float delta, Entity entity, TileWorld tileWorld)
|
|
|
|
{
|
|
|
|
Vector3 entityVelocity = entity.Velocity;
|
2022-12-31 18:36:52 +01:00
|
|
|
|
2023-01-03 17:46:55 +01:00
|
|
|
Vector2 currentTile = tileWorld.WorldToOffsetCoords(entity.GlobalTransform.origin);
|
|
|
|
Vector2 nextTile = tileWorld.WorldToOffsetCoords(entity.GlobalTransform.origin + entityVelocity * delta);
|
|
|
|
|
|
|
|
if (nextTile != currentTile)
|
|
|
|
{
|
|
|
|
float currentHeight = tileWorld.GetHeightAtOffset(currentTile);
|
|
|
|
float nextHeight = tileWorld.GetHeightAtOffset(nextTile);
|
|
|
|
|
|
|
|
bool isOnFloor = entity.IsOnFloor();
|
2023-11-10 11:11:08 +01:00
|
|
|
|
2023-01-03 17:46:55 +01:00
|
|
|
if (nextHeight - entity.GlobalTransform.origin.y > 0.1)
|
|
|
|
{
|
|
|
|
GD.Print("Jump!");
|
|
|
|
entityVelocity.y = 10;
|
2023-05-11 22:26:06 +02:00
|
|
|
|
|
|
|
Transform entityTransform = entity.GlobalTransform;
|
|
|
|
entityTransform.origin.y = nextHeight;
|
|
|
|
entity.GlobalTransform = entityTransform;
|
2023-01-03 17:46:55 +01:00
|
|
|
}
|
2022-12-28 21:57:34 +01:00
|
|
|
}
|
2022-12-31 18:36:52 +01:00
|
|
|
|
2023-01-03 17:46:55 +01:00
|
|
|
entityVelocity.y -= 9.81f * delta;
|
2023-11-10 11:11:08 +01:00
|
|
|
|
2023-01-03 17:46:55 +01:00
|
|
|
entity.Velocity = entityVelocity;
|
|
|
|
}
|
2023-11-10 11:11:08 +01:00
|
|
|
|
2023-11-10 12:22:17 +01:00
|
|
|
public void PhysicsProcess(float delta, Entity entity, Vector3 targetPosition, float targetAngle,
|
2023-11-10 11:11:08 +01:00
|
|
|
World world)
|
2023-01-03 17:46:55 +01:00
|
|
|
{
|
2023-11-10 11:11:08 +01:00
|
|
|
DirectionToTarget = targetPosition - entity.GlobalTranslation;
|
2023-10-27 23:00:54 +02:00
|
|
|
DirectionToTarget.y = 0;
|
|
|
|
DistanceToTarget = DirectionToTarget.Length();
|
|
|
|
|
|
|
|
if (DistanceToTarget >= Globals.EpsPosition)
|
|
|
|
{
|
|
|
|
DirectionToTarget = DirectionToTarget.Normalized();
|
|
|
|
TargetAngle = Vector3.Right.SignedAngleTo(DirectionToTarget, Vector3.Up);
|
2023-11-10 11:11:08 +01:00
|
|
|
TargetDeltaAngle = entity.CalcShortestPlaneRotationToTargetDirection(DirectionToTarget);
|
2023-10-27 23:00:54 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DirectionToTarget = Vector3.Right;
|
|
|
|
entity.GlobalTranslation = targetPosition;
|
|
|
|
entity.Velocity = new Vector3(0, entity.Velocity.y, 0);
|
2023-11-10 12:22:17 +01:00
|
|
|
|
|
|
|
if (entity.PlaneAngle != targetAngle)
|
|
|
|
{
|
|
|
|
Vector3 directionToTarget = Vector3.Right.Rotated(Vector3.Up, targetAngle);
|
|
|
|
TargetAngle = targetAngle;
|
|
|
|
TargetDeltaAngle = entity.CalcShortestPlaneRotationToTargetDirection(directionToTarget);
|
|
|
|
|
|
|
|
if (Mathf.Abs(TargetDeltaAngle) < Globals.EpsRadians)
|
|
|
|
{
|
|
|
|
TargetAngle = entity.PlaneAngle;
|
|
|
|
TargetDeltaAngle = 0;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2023-10-27 23:00:54 +02:00
|
|
|
}
|
2023-11-10 11:11:08 +01:00
|
|
|
|
2023-11-10 12:22:17 +01:00
|
|
|
CalcAndApplyOrientation(delta, entity, targetPosition, targetAngle);
|
|
|
|
|
2023-01-03 17:46:55 +01:00
|
|
|
CalcPlaneVelocity(delta, entity, targetPosition);
|
2023-10-27 23:00:54 +02:00
|
|
|
// CalcVerticalVelocity(delta, entity, tileWorld);
|
2023-01-03 17:46:55 +01:00
|
|
|
|
2022-12-31 18:36:52 +01:00
|
|
|
entity.Velocity = entity.MoveAndSlide(entity.Velocity);
|
2023-11-10 11:11:08 +01:00
|
|
|
|
2023-01-04 22:49:00 +01:00
|
|
|
//GD.Print("Pre : speed: " + prePhysicsVelocity.Length() + " Velocity: " + prePhysicsVelocity);
|
|
|
|
//GD.Print("Post: speed: " + entity.Velocity.Length() + " Velocity: " + entity.Velocity);
|
2022-12-28 21:57:34 +01:00
|
|
|
}
|
|
|
|
}
|