104 lines
3.7 KiB
C++
104 lines
3.7 KiB
C++
// Source/TengriPlatformer/Movement/TengriMovementComponent.h
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Components/ActorComponent.h"
|
|
#include "TengriPlatformer/Movement/Core/TengriMovementConfig.h"
|
|
#include "TengriMovementComponent.generated.h"
|
|
|
|
class UCapsuleComponent;
|
|
|
|
/**
|
|
* Custom movement component for deterministic 3D platformer physics.
|
|
* Handles acceleration, friction, gravity, collision, and ground snapping.
|
|
*/
|
|
UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
|
|
class TENGRIPLATFORMER_API UTengriMovementComponent : public UActorComponent
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UTengriMovementComponent();
|
|
|
|
protected:
|
|
virtual void BeginPlay() override;
|
|
|
|
public:
|
|
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
|
|
FActorComponentTickFunction* ThisTickFunction) override;
|
|
|
|
// ========================================================================
|
|
// BLUEPRINT API
|
|
// ========================================================================
|
|
|
|
/**
|
|
* Sets the movement input vector. Call every frame from PlayerController.
|
|
* @param NewInput - Raw input (will be clamped to 1.0 and Z zeroed)
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "Tengri Movement")
|
|
void SetInputVector(FVector NewInput);
|
|
|
|
// ========================================================================
|
|
// CONFIGURATION
|
|
// ========================================================================
|
|
|
|
/** Movement parameters data asset */
|
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Tengri Movement")
|
|
TObjectPtr<UTengriMovementConfig> MovementConfig;
|
|
|
|
// ========================================================================
|
|
// RUNTIME STATE
|
|
// ========================================================================
|
|
|
|
/** Current velocity in cm/s */
|
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Tengri Movement|State")
|
|
FVector Velocity;
|
|
|
|
/** True when character is on walkable ground */
|
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Tengri Movement|State")
|
|
bool bIsGrounded = false;
|
|
|
|
/** Cached surface thresholds (cosines) for performance */
|
|
UPROPERTY(VisibleAnywhere, Category = "Tengri Movement|Debug")
|
|
FSurfaceThresholds CachedThresholds;
|
|
|
|
private:
|
|
// ========================================================================
|
|
// INTERNAL STATE
|
|
// ========================================================================
|
|
|
|
UPROPERTY()
|
|
TObjectPtr<UCapsuleComponent> OwnerCapsule;
|
|
|
|
/** Normalized input vector (Z always 0) */
|
|
FVector InputVector = FVector::ZeroVector;
|
|
|
|
// ========================================================================
|
|
// INITIALIZATION
|
|
// ========================================================================
|
|
|
|
void InitializeSystem();
|
|
|
|
// ========================================================================
|
|
// MOVEMENT PHASES
|
|
// ========================================================================
|
|
|
|
/** Phase 1: Apply acceleration toward input direction or friction to stop */
|
|
void ApplyAccelerationAndFriction(float DeltaTime);
|
|
|
|
/** Phase 2: Rotate character to face movement direction */
|
|
void ApplyRotation(float DeltaTime) const;
|
|
|
|
/** Phase 3: Apply gravity when airborne */
|
|
void ApplyGravity(float DeltaTime);
|
|
|
|
/** Phase 4: Resolve movement with collision */
|
|
FVector ResolveMovementWithCollision(float DeltaTime);
|
|
|
|
/** Phase 5: Snap to ground to prevent slope jitter */
|
|
bool PerformGroundSnapping(FVector& InOutLocation, FHitResult& OutSnapHit) const;
|
|
|
|
/** Phase 6: Update grounded state based on collision results */
|
|
void UpdateGroundedState(bool bMoveBlocked, float HitNormalZ, bool bJustSnapped);
|
|
}; |