180 lines
7.7 KiB
TypeScript
180 lines
7.7 KiB
TypeScript
// Movement/Physics/BFL_Kinematics.ts
|
|
|
|
import type { DA_MovementConfig } from '#root/Movement/Core/DA_MovementConfig.ts';
|
|
import { BlueprintFunctionLibrary } from '#root/UE/BlueprintFunctionLibrary.ts';
|
|
import type { Float } from '#root/UE/Float.ts';
|
|
import { MathLibrary } from '#root/UE/MathLibrary.ts';
|
|
import { Vector } from '#root/UE/Vector.ts';
|
|
|
|
class BFL_KinematicsClass extends BlueprintFunctionLibrary {
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
// GROUND MOVEMENT
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* Calculate new velocity for ground-based movement with acceleration
|
|
* Uses VInterpTo for smooth acceleration towards target velocity
|
|
* Only affects horizontal (XY) components, preserves vertical (Z)
|
|
*
|
|
* @param CurrentVelocity - Current character velocity (cm/s)
|
|
* @param InputVector - Normalized input direction from player/AI
|
|
* @param DeltaTime - Frame delta time for frame-rate independence (s)
|
|
* @param Config - Movement configuration with MaxSpeed and Acceleration
|
|
* @returns New velocity vector with updated horizontal components
|
|
*
|
|
* @example
|
|
* // Character moving forward with input (1, 0, 0)
|
|
* const newVel = Kinematics.CalculateGroundVelocity(
|
|
* new Vector(400, 0, 0), // Current velocity
|
|
* new Vector(1, 0, 0), // Forward input
|
|
* 0.016, // 60 FPS delta
|
|
* config
|
|
* );
|
|
* // Returns: Vector(450, 0, 0) - accelerated towards MaxSpeed
|
|
*
|
|
* @pure true
|
|
* @category Ground Movement
|
|
*/
|
|
public CalculateGroundVelocity(
|
|
CurrentVelocity: Vector,
|
|
InputVector: Vector,
|
|
DeltaTime: Float,
|
|
Config: DA_MovementConfig
|
|
): Vector {
|
|
if (MathLibrary.VectorLength(InputVector) > 0.01) {
|
|
const CalculateTargetVelocity = (
|
|
inputVector: Vector,
|
|
maxSpeed: Float
|
|
): Vector =>
|
|
new Vector(
|
|
MathLibrary.Normal(inputVector).X * maxSpeed,
|
|
MathLibrary.Normal(inputVector).Y * maxSpeed,
|
|
MathLibrary.Normal(inputVector).Z * maxSpeed
|
|
);
|
|
|
|
return MathLibrary.VInterpTo(
|
|
new Vector(CurrentVelocity.X, CurrentVelocity.Y, 0),
|
|
CalculateTargetVelocity(InputVector, Config.MaxSpeed),
|
|
DeltaTime,
|
|
Config.Acceleration
|
|
);
|
|
} else {
|
|
return this.CalculateFriction(CurrentVelocity, DeltaTime, Config);
|
|
}
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
// FRICTION
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* Apply friction to horizontal velocity (deceleration when no input)
|
|
* Smoothly interpolates velocity towards zero using friction rate
|
|
* Only affects horizontal (XY) components, preserves vertical (Z)
|
|
*
|
|
* @param CurrentVelocity - Current character velocity (cm/s)
|
|
* @param DeltaTime - Frame delta time (s)
|
|
* @param Config - Movement configuration with Friction rate
|
|
* @returns New velocity vector with friction applied to horizontal components
|
|
*
|
|
* @example
|
|
* // Character sliding to stop after input released
|
|
* const newVel = Kinematics.ApplyFriction(
|
|
* new Vector(500, 0, 0), // Moving forward
|
|
* 0.016, // 60 FPS delta
|
|
* config // Friction = 8.0
|
|
* );
|
|
* // Returns: Vector(450, 0, 0) - smoothly decelerating
|
|
*
|
|
* @pure true
|
|
* @category Friction
|
|
*/
|
|
public CalculateFriction(
|
|
CurrentVelocity: Vector,
|
|
DeltaTime: Float,
|
|
Config: DA_MovementConfig
|
|
): Vector {
|
|
return MathLibrary.VInterpTo(
|
|
new Vector(CurrentVelocity.X, CurrentVelocity.Y, 0),
|
|
new Vector(0, 0, CurrentVelocity.Z),
|
|
DeltaTime,
|
|
Config.Friction
|
|
);
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
// GRAVITY
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* Apply gravity to vertical velocity when airborne
|
|
* Only affects Z component, horizontal velocity unchanged
|
|
* Gravity is NOT applied when grounded (Z velocity set to 0)
|
|
*
|
|
* @param CurrentVelocity - Current character velocity (cm/s)
|
|
* @param IsGrounded - Whether character is on walkable surface
|
|
* @param Config - Movement configuration with Gravity force
|
|
* @returns New velocity vector with gravity applied to vertical component
|
|
*
|
|
* @example
|
|
* // Character falling (not grounded)
|
|
* const newVel = Kinematics.ApplyGravity(
|
|
* new Vector(500, 0, -200), // Moving forward and falling
|
|
* false, // Not grounded
|
|
* config // Gravity = 980 cm/s²
|
|
* );
|
|
* // Returns: Vector(500, 0, -216.8) - falling faster
|
|
*
|
|
* @example
|
|
* // Character on ground
|
|
* const newVel = Kinematics.ApplyGravity(
|
|
* new Vector(500, 0, -10), // Small downward velocity
|
|
* true, // Grounded
|
|
* config
|
|
* );
|
|
* // Returns: Vector(500, 0, 0) - vertical velocity zeroed
|
|
*
|
|
* @pure true
|
|
* @category Gravity
|
|
*/
|
|
public CalculateGravity(
|
|
CurrentVelocity: Vector,
|
|
IsGrounded: boolean,
|
|
Config: DA_MovementConfig
|
|
): Vector {
|
|
if (!IsGrounded) {
|
|
return new Vector(
|
|
CurrentVelocity.X,
|
|
CurrentVelocity.Y,
|
|
CurrentVelocity.Z - Config.Gravity
|
|
);
|
|
} else {
|
|
return new Vector(CurrentVelocity.X, CurrentVelocity.Y, 0);
|
|
}
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
// VELOCITY QUERIES
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* Get horizontal speed (magnitude of XY velocity)
|
|
* Ignores vertical component, useful for animation and debug display
|
|
*
|
|
* @param Velocity - Velocity vector to measure
|
|
* @returns Speed in cm/s (horizontal plane only)
|
|
*
|
|
* @example
|
|
* const speed = Kinematics.GetHorizontalSpeed(new Vector(300, 400, -100));
|
|
* // Returns: 500.0 (sqrt(300² + 400²))
|
|
*
|
|
* @pure true
|
|
* @category Velocity Queries
|
|
*/
|
|
public GetHorizontalSpeed(Velocity: Vector): Float {
|
|
return MathLibrary.VectorLength(new Vector(Velocity.X, Velocity.Y, 0));
|
|
}
|
|
}
|
|
|
|
export const BFL_Kinematics = new BFL_KinematicsClass();
|