6


개발해야되는데 하기 싫어서 글이나 써봄



오래전부터 내가 유용하게 써먹는 Trace 기능을 소개해볼게




viewimage.php?id=2abcdd23dad63db0&no=24b0d769e1d32ca73ce884fa1bd6253119da20824c04b6efd9ad482f5cc5f7af27605daed6e7e290065a6babc48ed50411b050fa51eac1c6bfd19326ec9bd56f8cd7365540


이번 글은 사진같은 Trace 에 관한 글임





viewimage.php?id=2abcdd23dad63db0&no=24b0d769e1d32ca73ce884fa1bd6253119da20824c04b6efd9ad482f5cc5f7af27605daed6e7e290065a6babc48ed50411b050fa51eac1c6bfdf9473ebca82694964e3e429


보통 Melee Trace를 구현하면 젤 첨에 하는게 이런식으로 칼 윗부분과 아랫부분을 잇는 Trace를 만들거나 칼 모양 Collision 하나 달아주곤함

근데 사진에서 볼 수 있다시피 중간에 궤적에 공백이 생길 수가 있음


사실 큰 문제는 없는데 간지가 안나잖아

20






그래서 이걸 해결하는 코드를 작성해보도록 하자



준비물


1. Ctrl+C, Ctrl+V 에 대한 이해

2. Unreal Engine




3. 

viewimage.php?id=2abcdd23dad63db0&no=24b0d769e1d32ca73ce884fa1bd6253119da20824c04b6efd9ad482f5cc5f7af27605daed6e7e290065a6babc48ed50411b050fa51eac1c6bfdec021e8ced569c0fef81d58

메쉬에 소켓 달아줌





헤더

UPROPERTY(EditDefaultsOnly, Category = "Attack")
TArray<FName> TraceSocketNameArray;
UPROPERTY(EditDefaultsOnly, Category = "Attack")
FVector TraceSize;

TMap<FName, FVector> UpdateTraceLocationMap;

TArray<AActor*> HitActors;

TraceSocketNameArray - 메쉬에 달린 소켓 이름 배열

TraceSize - Trace 크기 조절용

UpdateTraceLocationMap - 소켓 위치에 따른 Trace 위치 업데이트용 컨테이너

HitActors - 중복처리용



CPP

void UGAB_AttackSword::OnAttackTraceBegin()
{
for (auto TraceSocketName : TraceSocketNameArray)
{
UpdateTraceLocationMap.Add(TraceSocketName, WeaponComponent->GetSocketLocation(TraceSocketName));
}
}

AnimNotifyState Begin 함수에서 Trace 시작 위치 지정을 위해 컨테이너 초기화해줌


void UGAB_AttackSword::OnAttackTraceTick()
{
AActor* AvatarActor = GetAvatarActorFromActorInfo();
if (!AvatarActor) return;

for (auto TraceSocketName : TraceSocketNameArray)
{
FVector Start = UpdateTraceLocationMap[TraceSocketName];
FVector End = WeaponComponent->GetSocketLocation(TraceSocketName);
FRotator Rotation = WeaponComponent->GetSocketRotation(TraceSocketName);

TArray<FHitResult> HitResults;
UKismetSystemLibrary::BoxTraceMulti(GetWorld(), Start, End, TraceSize, Rotation, TRACE_TYPE_SWORD, true, {AvatarActor}, EDrawDebugTrace::ForDuration, HitResults, true);

for (auto HitResult : HitResults)
{
if (AEnemyCharacterBase* HitEnemy = Cast<AEnemyCharacterBase>(HitResult.GetActor()))
{
if (!HitActors.Contains(HitEnemy))
{
HitActors.Add(HitEnemy);
// 대미지 여기서 처리
}
}
}

UpdateTraceLocationMap[TraceSocketName] = WeaponComponent->GetSocketLocation(TraceSocketName);
}
}

Tick에서 Trace 해주면됨


위에 AvatarActor는 귀찮아서 GAS로 작업한거 그대로 들고오느라 냅뒀음. 예외처리용임.


Rotation 쓰려고 BoxTraceMulti로 해줬는데 굳이 필요없다 싶으면 다른걸로 해도됨.


여긴 뭐 별건 없는데 마지막부분


우리의 컨테이너 (Start Vector) 를 다음 프레임에 소켓 위치로 업데이트 해줘야 제대로 이어지게됨



void UGAB_AttackSword::OnAttackTraceEnd()
{
if (HitActors.Num() > 0)
HitActors.Empty();
}

End에서 꼭 HitActor를 비워줘야됨




7de99e36ebd518986abce8954780766431


마지막으로 Array 넣어주고 Trace Size 지정해주면 끝







168ef807cbf305826bacdda119c1646fdfcc1e1b634d85af792b80d5f72cba3f31e2c57e50103d3fd80b2146f9c4c7d129f8b3172bdfb33a7c54


결과물.

궤적 보여주려고 Size 작게함





5분만에 당신도 액션겜 개발 고수

11









사실 무료 플러그인 쓰면 내거보다 좋음