JIN

[UE5] 플레이어 공격의 충돌 처리 ( ShapeComponent Sweep ) [1]

destroyer 2024. 10. 29. 17:19

플레이어 타격 충돌 처리

전투 시스템에서 타격 판정은 매우 중요한 요소이다. 정교하게 타격 판정이 이루어 질 수록 타격 감각을 세밀하게 구현할 수 있다.

특히 속도가 빠른 애니메이션의 경우, 프레임 단위로 충돌 체크를 하면 타격 판정에 빈 구간이 눈에 띄게 나타난다.

타격에 빈 구간이 많은 기본 충돌 체크

기본 선형 보간

void AM4_PlayerWeaponSword::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
    FVector CapsuleLocation = CapsuleComp->GetComponentLocation();
    FVector CurrentWeaponLoc = CapsuleComp->GetComponentLocation();
    float CapsuleHalfHeight = CapsuleComp->GetScaledCapsuleHalfHeight();
    float CapsuleRadius = CapsuleComp->GetScaledCapsuleRadius();

    // 이전 위치가 설정되지 않은 경우 초기화
    if (PrevWeaponLoc.IsZero())
    {
        PrevWeaponLoc = CurrentWeaponLoc;
        return;
    }

    // 충돌 감지가 활성화된 경우에만 실행
    if (bOnCollision)
    {
        FVector Trajectory = CurrentWeaponLoc - PrevWeaponLoc;
        int NumSteps = FMath::CeilToInt(Trajectory.Size() / 20.0f); // 보간 스텝 수 결정

        for (int i = 0; i <= NumSteps; ++i)
        {
            float Alpha = i / static_cast<float>(NumSteps);
            FVector InterpolatedPosition = FMath::Lerp(PrevWeaponLoc, CurrentWeaponLoc, Alpha);

            // 보간된 위치에서의 충돌 처리 추가하기

            // 디버그 캡슐을 표시하여 궤적 시각화
            DrawDebugCapsule(GetWorld(), InterpolatedPosition, CapsuleHalfHeight, CapsuleRadius, GetActorRotation().Quaternion(), FColor::Green, false, 0.1f);

        }

    }
    // 이전 위치 업데이트
    PrevWeaponLoc = CurrentWeaponLoc;
}

이전 위치를 저장해두고, 보간 Step만큼 반복하여 현재 위치와 이전 위치를 선형 보간하는 방식으로 구현했다.

 

키 프레임 콜리전 위치 예시

다음과 같이 키 프레임 이 존재한다고 했을 때

 

위치 보간 작용

이러한 방식으로 콜리전의 위치를 보간 하여 빈 공간을 메꾸는 방식

 

빈 공간이 확연이 사라진 것을 볼 수 있었다.

 

하지만 검을 휘두른다고 생각했을 때 머릿속에서 생각나는 궤적과는 차이가 나는 모습. 검이 원형을 그리며 부드럽게 그려지지 않고 각진 형태로 그려진다.