9#include "CoreMinimal.h"
11#include "Components/ActorComponent.h"
12#include "UParabolaComponent.generated.h"
18 Ballistic
UMETA(DisplayName=
"Physics (Ballistic)", ToolTip=
"Start + V0*t + 0.5*g*t^2"),
20 Geometric
UMETA(DisplayName=
"Geometric (Apex Height)", ToolTip=
"Lerp(Start,Target,a) + UpAxis * 4*H*a*(1-a)")
34 UPROPERTY(EditAnywhere, BlueprintReadWrite) FVector Start = FVector::ZeroVector;
35 UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(ClampMin="0.001"))
float Duration = 1.0f;
36 UPROPERTY(EditAnywhere, BlueprintReadWrite)
float GravityZ = -980.f;
37 UPROPERTY(EditAnywhere, BlueprintReadWrite) FVector Direction = FVector(1,0,0);
38 UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(ClampMin="0.0"))
float Power = 1200.f;
41 UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool bLockZ = false;
42 UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(EditCondition="bLockZ"))
float LockedZ = 0.f;
45 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Transient)
float CurrentTime = 0.f;
49 FORCEINLINE
void ResetTime() { CurrentTime = 0.f; }
51 FORCEINLINE
float GetAlpha()
const {
return FMath::Clamp(CurrentTime / FMath::Max(0.001f, Duration), 0.f, 1.f); }
55 CurrentTime = FMath::Min(CurrentTime + FMath::Max(0.f, DeltaTime), FMath::Max(0.001f, Duration));
62 return Direction.GetSafeNormal() * Power;
68 const float t = FMath::Clamp(TimeSec, 0.f, FMath::Max(0.001f, Duration));
69 const FVector g(0,0,GravityZ);
70 const FVector V0 = GetInitialVelocity();
72 FVector P = Start + V0 * t + 0.5f * g * t * t;
81 return EvaluateAtTime(Owner, Alpha * FMath::Max(0.001f, Duration));
87 return EvaluateAtTime(Owner, CurrentTime);
92 static FVector
SolveV0ForArc(
const FVector& InStart,
const FVector& InEnd,
float t,
float InGravityZ=-980.f)
98 static void SplitVelocity(
const FVector& V0, FVector& OutDir,
float& OutPow)
100 OutPow = V0.Length();
101 OutDir = (OutPow > SMALL_NUMBER) ? V0 / OutPow : FVector(1,0,0);
108 Duration = FMath::Max(0.001f, t);
109 const FVector V0 = SolveV0ForArc(InStart, InEnd, Duration, GravityZ);
110 SplitVelocity(V0, Direction, Power);
116USTRUCT(BlueprintType)
122 UPROPERTY(EditAnywhere, BlueprintReadWrite) FVector Start = FVector::ZeroVector;
123 UPROPERTY(EditAnywhere, BlueprintReadWrite) FVector Target = FVector::ZeroVector;
124 UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(ClampMin="0.001"))
float Duration = 1.0f;
125 UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(ClampMin="0.0"))
float ApexHeight = 200.f;
126 UPROPERTY(EditAnywhere, BlueprintReadWrite) FVector UpAxis = FVector::UpVector;
129 UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool bLockZ = false;
130 UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(EditCondition="bLockZ"))
float LockedZ = 0.f;
133 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Transient)
float CurrentTime = 0.f;
137 FORCEINLINE
void ResetTime() { CurrentTime = 0.f; }
139 FORCEINLINE
float GetAlpha()
const {
return FMath::Clamp(CurrentTime / FMath::Max(0.001f, Duration), 0.f, 1.f); }
143 CurrentTime = FMath::Min(CurrentTime + FMath::Max(0.f, DeltaTime), FMath::Max(0.001f, Duration));
150 const float D = FMath::Max(0.001f, Duration);
151 const float t = FMath::Clamp(TimeSec, 0.f, D);
152 const float a = t / D;
160 return EvaluateAtTime(Owner, Alpha * FMath::Max(0.001f, Duration));
166 return EvaluateAtTime(Owner, CurrentTime);
170 void ApplyArcSolution(
const FVector& InStart,
const FVector& InTarget,
const float InApexHeight,
float t,
const FVector& InUpAxis = FVector::UpVector)
174 ApexHeight = FMath::Max(0.f, InApexHeight);
176 Duration = FMath::Max(0.001f, t);
185UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
186class COFFEELIBRARY_API UParabolaComponent :
public UActorComponent
191 UParabolaComponent();
195 virtual
void BeginPlay() override;
199 virtual
void TickComponent(
float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
201 void UpdateTracks(
float DeltaTime);
204 UFUNCTION(BlueprintCallable, Category="Parabola")
205 FRotator GetParabolaFacing(FName TrackName,
bool bYawOnly,
EForwardAxis ForwardAxis) const;
208 UFUNCTION(BlueprintCallable, Category="Parabola")
209 FRotator MakeFacingFromDir(const FVector& Direction, const
bool bYawOnly, const
EForwardAxis ForwardAxis) const;
213 UFUNCTION(BlueprintCallable, Category="Parabola|Ballistic")
217 UFUNCTION(BlueprintPure, Category="Parabola|Ballistic")
218 FVector GetBallisticParabolaVectorTrack(FName TrackName) const;
221 UFUNCTION(BlueprintPure, Category="Parabola|Ballistic")
222 FVector GetBallisticVectorAtAlphaFromTrack(FName TrackName,
float Alpha) const;
225 UFUNCTION(BlueprintCallable, Category="Parabola|Ballistic")
226 void DrawBallisticPath(FName TrackName, int32 NumSegments, FColor
Color,
float LifeTime) const;
230 UFUNCTION(BlueprintCallable, Category="Parabola|Geometric")
234 UFUNCTION(BlueprintPure, Category="Parabola|Geometric")
235 FVector GetGeometricParabolaVectorTrack(FName TrackName) const;
238 UFUNCTION(BlueprintPure, Category="Parabola|Geometric")
239 FVector GetGeometricVectorAtAlphaFromTrack(FName TrackName,
float Alpha) const;
242 UFUNCTION(BlueprintCallable, Category="Parabola|Geometric")
243 void DrawGeometricPath(FName TrackName, int32 NumSegments, FColor
Color,
float LifeTime) const;
EForwardAxis
정면 방향 축을 지정한다.
EParabolaType
포물선 트랙 계산 방식을 정의한다.
static FVector InterpArcSin(const FVector &Start, const FVector &End, float Height, float Alpha)
선형 보간 경로에 사인 함수를 더해 아치 형태의 곡선을 생성합니다.
static FVector SolveV0ForProjectile(const FVector &Start, const FVector &End, float Time, float GravityZ=-980.f)
주어진 시간 안에 목표 지점에 도달하기 위한 초기 속도를 계산합니다.
물리 기반(초기 속도/중력) 포물선을 계산하는 트랙.
FORCEINLINE FVector GetInitialVelocity() const
방향/파워 조합으로부터 초기 속도를 계산한다.
static void SplitVelocity(const FVector &V0, FVector &OutDir, float &OutPow)
속도를 방향과 크기로 분해한다.
FORCEINLINE FVector EvaluateAtCurrent(const AActor *Owner) const
현재 시간 기준 위치를 계산한다.
FVector EvaluateAtTime(const AActor *, float TimeSec) const
시간값을 받아 포물선 위치를 계산한다.
void ApplyArcSolution(const FVector &InStart, const FVector &InEnd, float t)
시작/도착점과 시간으로 트랙 파라미터를 초기화한다.
FORCEINLINE FVector EvaluateAtAlpha(const AActor *Owner, float Alpha) const
알파값 기반 위치를 계산한다.
FORCEINLINE float GetAlpha() const
현재 경과 시간의 알파를 반환한다.
static FVector SolveV0ForArc(const FVector &InStart, const FVector &InEnd, float t, float InGravityZ=-980.f)
목표 위치와 비행 시간으로 초기 속도를 역산한다.
FORCEINLINE void Advance(float DeltaTime)
지정한 델타만큼 시간을 진행한다.
정점 높이를 지정해 기하학적 포물선을 계산하는 트랙.
FORCEINLINE FVector EvaluateAtAlpha(const AActor *Owner, float Alpha) const
알파값 기반 위치를 계산한다.
FVector EvaluateAtTime(const AActor *, float TimeSec) const
시간값을 받아 포물선 위치를 계산한다.
FORCEINLINE void Advance(float DeltaTime)
지정한 델타만큼 시간을 진행한다.
void ApplyArcSolution(const FVector &InStart, const FVector &InTarget, const float InApexHeight, float t, const FVector &InUpAxis=FVector::UpVector)
시작/도착점과 정점 높이로 트랙 파라미터를 초기화한다.
FORCEINLINE float GetAlpha() const
현재 경과 시간의 알파를 반환한다.
FORCEINLINE FVector EvaluateAtCurrent(const AActor *Owner) const
현재 시간 기준 위치를 계산한다.