Shift키를 눌러서 Dash를 실행할 때, Niagara VFX를 이용하여 이펙트를 구현하였다.
이 기능의 문제점은 SpawnSystemAtLocation을 이용해 일정한 크기 값으로 스폰하기 때문에 막상 어떤 물체에 막혀 이동한 거리가 짧아도 이펙트는 정해진 길이만큼 출력되는 문제가 존재하였다.
이를 LineTrace기능을 이용하여 앞에 액터가 있는지 확인 후 있으면 그 액터와의 거리를 크기로 변환하여 이펙트의 크기를 줄이고, 없으면 정해진 길이만큼 스폰되도록 변경하였다.
// TOCharacter.cpp
void ATOCharacter::Dash()
{
if (!GetCharacterMovement()->IsFalling())
{
if (!IsDashCoolDown)
{
// Line Trace를 위한 벡터 확인
FVector LineTraceEnd = GetActorLocation() + GetActorRotation().Vector() * 500.0f;
DrawDebugLine (
GetWorld(),
GetActorLocation(),
LineTraceEnd,
FColor(255, 0, 0),
false,
10.f,
0.f,
10.f
);
FCollisionQueryParams TraceParameters(NAME_None, false, this);
// 라인트레이스
FHitResult HitResult;
bool IsHitResult = GetWorld()->LineTraceSingleByChannel (
HitResult,
GetActorLocation(),
LineTraceEnd,
ECollisionChannel::ECC_GameTraceChannel1,
TraceParameters
);
if (IsHitResult)
{
ABLOG(Warning, TEXT("HIT!"));
AActor* ActorHit = HitResult.GetActor();
if (ActorHit)
{
float distance = GetDistanceTo(ActorHit);
ABLOG(Warning, TEXT("Distance : %.2f"), distance);
UNiagaraComponent* ActiveDashEffect = UNiagaraFunctionLibrary::SpawnSystemAtLocation(GetWorld(), DashEffect, FVector(GetActorLocation()), FRotator(GetActorRotation()), FVector(distance / 1000.0f, 1.0f, 1.0f), true);
}
}
else
{
ABLOG(Warning, TEXT("NONE"));
UNiagaraComponent* ActiveDashEffect = UNiagaraFunctionLibrary::SpawnSystemAtLocation(GetWorld(), DashEffect, FVector(GetActorLocation()), FRotator(GetActorRotation()), FVector(0.5f, 1.0f, 1.0f), true);
}
//WalkSpeed와 가속도를 바꾸어 Dash를 실행한다.
GetCharacterMovement()->MaxWalkSpeed = 2000.0f;
GetCharacterMovement()->MaxAcceleration = 20000.0f;
DashTimeline.PlayFromStart();
...
}
}
}
먼저 라인트레이스의 길이를 정한다.
GetActorLocation() + GetActorRotation().Vector() * 500.0f; 로 현재 장소에서 방항값에 500.0f를 곱하여 길이를 설정하였다.
FCollisionQueryParams TraceParameters(NAME_None, false, this);
자기 자신(Character)을 라인 트레이스 detect에서 제외시킨다.
bool IsHitResult = GetWorld()->LineTraceSingleByChannel (
HitResult,
GetActorLocation(),
LineTraceEnd,
ECollisionChannel::ECC_GameTraceChannel1,
TraceParameters
);
SingleByChannel은 맞은 액터를 통과하지 않고 처음으로 맞은 단 하나의 액터만 확인한다.
현재 장소에서 LineTraceEnd까지 라인 트레이스를 진행하면서 맞은 액터가 있는지 확인한다.
IsHitResult에서 값이 true면 캐릭터와 맞은 액터와의 거리값을 구한 후, 이펙트의 크기를 수정한다.
false인 경우 정적인 크기(0.5f로 설정)로 이펙트가 생성된다.
결과는 다음과 같다.
'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 개발 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 부탁드립니다!