캐릭터의 Dash를 구현할 때, Launch Character를 사용하여 구현하면 간단하지만 공중으로 Dash할 때와 지면에서 Dash할 때의 이동 거리가 다르다는 문제점이 발생하였다.
이는 지면에 있을 때엔 지면 마찰(CharacterMovement에 Ground Scale)의 영향을 받기 때문에 지면에서는 적게 가지만, 공중에서는 지면 마찰을 받지 않기 때문에 일어나는 현상이다.
이를 Timeline을 사용한 방법으로 수정하여 보자.
먼저, 언리얼 에디터에서 기타 → 커브로 해서 커브를 제작한다.
CurveFloat을 사용해 (0, 0), (0.25, 1)의 값을 가지는 커브를 구현하였다.
//Character.h
public:
//타임라인에 사용할 Curve
UPROPERTY(EditAnywhere)
UCurveFloat* DashCurve;
private:
//타임라인에 사용되는 델리게이트
FOnTimelineFloat DashTimeLineUpdateDelegate;
FOnTimelineEvent DashTimeLineFinishDelegate;
//타임라인
FTimeline DashTimeline;
//각각 Dash를 시작할 때, 끝날 때 사용할 함수 목록
UFUNCTION()
void DashStart(float Output);
UFUNCTION()
void DashEnd();
//Character.cpp
ATOCharacter::ATOCharacter()
{
const ConstructorHelpers::FObjectFinder<UCurveFloat> Curve(TEXT("/Game/Tellours/Developer/TimeLine/CF_Dash.CF_Dash"));
if (Curve.Succeeded())
{
DashCurve = Curve.Object;
}
if (DashCurve != nullptr)
{
DashTimeLineUpdateDelegate.BindUFunction(this, FName("DashStart"));
DashTimeLineFinishDelegate.BindUFunction(this, FName("DashEnd"));
DashTimeline.AddInterpFloat(DashCurve, DashTimeLineUpdateDelegate);
DashTimeline.SetTimelineFinishedFunc(DashTimeLineFinishDelegate);
float Min = 0.0f;
float Max = 0.25f;
DashCurve->GetTimeRange(Min, Max);
DashTimeline.SetTimelineLength(Max);
}
}
void ATOCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
//Dash 타임라인 관련
DashTimeline.TickTimeline(DeltaTime);
}
void ATOCharacter::Dash()
{
if (!GetCharacterMovement()->IsFalling())
{
if (!IsDashCoolDown)
{
GetCharacterMovement()->MaxWalkSpeed = 2000.0f;
GetCharacterMovement()->MaxAcceleration = 20000.0f;
DashTimeline.PlayFromStart();
}
}
}
void ATOCharacter::DashStart(float Output)
{
AddMovementInput(GetCapsuleComponent()->GetForwardVector(), 1.0f, false);
}
void ATOCharacter::DashEnd()
{
GetCharacterMovement()->MaxWalkSpeed = 600.0f;
GetCharacterMovement()->MaxAcceleration = 2048.0f;
}
.h 파일에는 사용할 커브, 연결할 델리게이트, 타임라인 본체, 타임라인의 시작과 끝에 사용할 함수를 명시해준다.
이 때, 타임라인에 사용할 함수들은 UFUNCTION()을 반드시 입력해야 한다.
이후 사용할 .cpp에 생성자에서 ConstructorHelpers::FObjectFinder를 이용하여 이전에 만들어 둔 커브를 가져온다.
DashTimeLineUpdateDelegate.BindUFunction(this, FName("DashStart"));
DashTimeLineFinishDelegate.BindUFunction(this, FName("DashEnd"));
DashTimeline.AddInterpFloat(DashCurve, DashTimeLineUpdateDelegate);
DashTimeline.SetTimelineFinishedFunc(DashTimeLineFinishDelegate);
float Min = 0.0f;
float Max = 0.25f;
DashCurve->GetTimeRange(Min, Max);
DashTimeline.SetTimelineLength(Max);
시작 델리게이트에 “DashStart”라는 이름을 가진 함수를 지정해주고, 끝 델리게이트에 “DashEnd”라는 이름을 가진 함수를 지정해준다.
이를 AddInterp, SetTimelineFinishedFunc를 이용해 FloatTimeline에 연결하는 작업을 거친다.
Curve에서 내가 사용할 정확한 길이를 가져오기 위해 Min, Max를 이용해 가져온다.
위에서 (0, 0), (0.25, 1)을 지정하였으므로 0~0.25의 값을 가져오기 위해 Min, Max를 설정, Curve의 값을 불러와서 타임라인의 길이를 지정해줬다.
Tick()에서 타임라인을 실행하기 위해 DashTimeline.TickTimeline(DeltaTime);로 등록해둔다.
GetCharacterMovement()->MaxWalkSpeed = 2000.0f;
GetCharacterMovement()->MaxAcceleration = 20000.0f;
DashTimeline.PlayFromStart();
캐릭터의 걷기 속도와, 가속도 값을 변경하고 타임라인을 실행한다.
타임라인이 실행되면 Tick()에서 프레임값으로 정해진 시간만큼 실행하게 되고 시작할 때는 “DashStart”, 끝날 때는 “DashEnd”가 실행된다.
결과는 다음과 같다.
'UnrealEngine > 공부' 카테고리의 다른 글
[Unreal Engine C++] 특정 위치로의 레벨 텔레포트의 구현 (1) | 2024.02.27 |
---|---|
[Unreal Engine C++] 연속 공격의 구현 (0) | 2024.02.27 |
[Unreal Engine C++] SaveData의 구현 (0) | 2024.02.27 |
[Unreal Engine C++] Dash의 이펙트 구현 (0) | 2024.02.27 |
[Unreal Engine C++] UI IMAGE Animation 적용 (0) | 2024.01.17 |
CSE & GAME 개발 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 부탁드립니다!