기본공격 판정방법 변경 1
위 링크를 타고 들어 가면 애님스테이트를 활용해서 충돌처리를 적용하는 것을 확인해 볼 수 있습니다.
부끄럽지만 솔직하게 말하면은 처음에는 당연히 문제가 없을 거라고 생각했습니다.
프레임이 떨어져도 과거의 제가 봤을 때는 어느정도 촘촘하게 라인트레이스가 나오는 게 보였고 이 정도면 충돌처리하는데 문제가 없겠다!라고 생각을 했습니다.
문제가 없겠지라고 생각은 했지만 이 마음속에 남아있는 이 찜찜함이 저를 못놔주고 있던 와중 언리얼 페스타를 가게 되었습니다.
네트워크 최적화,넥스트 스테이지의 언리얼 GAS사용법등 흥미로운 강연을 볼 수 있었고 시프트업의 스텔라 블레이드에서 활용한 여러가지 기법을 볼 수 있었습니다.
이제 본론으로 돌아와서 스텔라블레이드에서 충돌처리 기법에 대해서 설명을 해주었는데 정교한 충돌을 위한 방법을 설명해주었습니다.
애님스테이트를 활용하여 충돌처리를 진행하는 방법은 같았으나 이제 다음 스탭으로 프레임과 프레임 사이에 비어있는 공간에 대한 충돌처리를 어떻게 할 것인가에 대한 고민 및 해결 방법을 볼 수 있었습니다.
이 때 속마음으로는 와!이거다!하면서 좋아했던 기억이 있습니다.ㅋㅋㅋ
프레임이 떨어지게 되면 충돌처리가 발생하지 않을 수 있다.
공격속도가 빨라지게 되면 충돌처리가 발생하지 않을 수 있다.
->빈 공간이 현재 충돌처리가 안되는 부분
1.프레임과 프레임 사이를 삼각형으로 채운다
2. 프레임과 프레임 사이를 보간하여 라인트레이스를 촘촘하게 채워준다.
// Start와 End 위치의 중간 지점 계산
FVector PrevMiddleLocation = (PrevStartLocation + PrevEndLocation) / 2;
FVector CurrentMiddleLocation = (CurrentStartLocation + CurrentEndLocation) / 2;
// 첫 번째 삼각형: PrevStart -> CurrentStart -> PrevMiddle
PerformTriangleTrace(Owner, PrevStartLocation, CurrentStartLocation, PrevMiddleLocation, HitResults);
// 두 번째 삼각형: CurrentStart -> CurrentMiddle -> PrevMiddle
PerformTriangleTrace(Owner, CurrentStartLocation, CurrentMiddleLocation, PrevMiddleLocation, HitResults);
// 추가 삼각형 1: PrevMiddle -> CurrentMiddle -> PrevEnd
PerformTriangleTrace(Owner, PrevMiddleLocation, CurrentMiddleLocation, PrevEndLocation, HitResults);
// 추가 삼각형 2: CurrentStartLocation -> PrevEnd -> CurrentEnd
PerformTriangleTrace(Owner, CurrentMiddleLocation, PrevEndLocation, CurrentEndLocation, HitResults);
1.전의 지점과 현재 지점을 거리의 비율에 맞게 보간하여 나누어 줍니다.
칼은 곡선으로 휘게 되는데 사진과 같이 직선으로 나오는 것을 확인해볼 수 있습니다.
다음 방법으로 이를 해결해보도록 하겠습니다.
2.칼의 곡선을 위해 베지어 곡선을 이용하여 보간해줍니다.
중간점은 현재 라인과 이전 라인의 중간값을 구해줍니다.
중간점을 중간선의 방향벡터*보정값만큼 이동하여 줍니다.
보정값은 위 그림의 빨간선 길이 및 파란선 2개의 내적값을 구하여 추출해줍니다.
// 보간을 위해 이전 지점과 현재 지점 사이의 거리 계산
float DistanceStart = FVector::Dist(PrevStartLocation, CurrentStartLocation);
float DistanceEnd = FVector::Dist(PrevEndLocation, CurrentEndLocation);
FVector EndDirection = (CurrentEndLocation - PrevEndLocation).GetSafeNormal();
FVector StartDirection = (CurrentStartLocation - PrevStartLocation).GetSafeNormal();
float DotProduct = FVector::DotProduct(EndDirection, StartDirection);
float AngleRadians = FMath::Acos(DotProduct);
// 라디안 값을 도 단위로 변환
float AngleDegrees = FMath::RadiansToDegrees(AngleRadians);
float AngleRatio = 180.0f/(AngleDegrees);
// 보간할 간격(거리가 일정 이상일 경우 보간 수행)
float InterpolationStep = 5.0f; // 간격을 설정
int32 NumStepsStart = FMath::CeilToInt(DistanceStart / AngleRatio);
int32 NumStepsEnd = FMath::CeilToInt(DistanceEnd / AngleRatio);
int32 NumSteps = FMath::CeilToInt(DistanceStart / InterpolationStep);
// 2차 베지어 곡선을 위한 제어점 계산
FVector ControlPointStart = (PrevStartLocation + CurrentStartLocation) / 2 ; // 임의로 위로 올린 제어점
FVector ControlPointEnd = (PrevEndLocation + CurrentEndLocation) / 2 ;
FVector ControlPointDirection = (ControlPointStart - ControlPointEnd).GetSafeNormal();
ControlPointStart=ControlPointStart+ControlPointDirection*-NumStepsStart;
ControlPointEnd=ControlPointEnd+ControlPointDirection*-NumStepsEnd;
//베지어 커브 계산
FVector InterpolatedStart = BezierCurve(PrevStartLocation, ControlPointStart, CurrentStartLocation, Alpha);
FVector InterpolatedEnd=BezierCurve(PrevEndLocation,ControlPointEnd,CurrentEndLocation,Alpha);
- 충돌 처리 방법을 보간하는 방법으로 바꿈으로서 보다 정확하게 판정할 수 있게 되었습니다.
- 정확한 판정을 위해서는 다양한 방법을 사용해야한다는 것을 알 수 있었습니다.
- 다음에는 AI와 GAS를 활용하는 방법을 연구해보도록 하겠습니다.