📘Unreal Engine/📝Unreal Engine
[Unreal Engine] 충돌 판정 / 트레이싱 (Tracing)
주으기
2024. 8. 9. 14:07
728x90
반응형
트레이싱 함수를 사용하여 물체의 충돌을 감지하는 방법에 대한 설명 글이다.
트레이싱 함수
물체의 충돌을 감지하는 방법 중 가장 대표적으로 트레이싱 함수가 있다.
트레이싱 함수의 이름은 세 가지 카테고리의 이름을 붙여 결정된다.
1. 충돌 방법
- LineTrace : 지정한 방향으로 선을 투사하여, 이 선이 물체와 충돌하는지 감지한다.
- Sweep : 선이 아닌 도형(구체, 박스 등)을 투사하여 충돌을 감지한다.
- Overlap : 지정한 영역(구체, 박스 등) 내에 충돌하는 물체가 있는지 감지한다.
2. 충돌 대상
- Test : 충돌 여부를 단순히 테스트하여 반환한다.
- Single : 충돌이 감지된 단일 물체에 대한 정보를 반환한다.
- Multi : 충돌이 감지된 모든 물체의 정보를 배열로 반환한다.
LineTrace와 Sweep의 경우 Single이 붙는다.
Overlap의 경우 AnyTest가 붙는다.
3. 충돌 설정
- ByChannel : 물체의 트레이스 채널 정보를 사용하여 충돌 대상을 감지한다.
- ByObjectType : 물체의 오브젝트 타입을 사용하여 충돌 대상을 감지한다.
- ByProfile : 물체의 콜리전 프로필 정보를 사용하여 충돌 대상을 감지한다.
위 세 가지 이름 분류를 연결하여 함수 이름이 완성된다. {충돌 방법}{충돌 대상}{충돌 설정}
// ex.1
// 캐릭터의 시선 방향으로 작은 구체를 투사하여 구체 범위 내의 물체를 감지
// 처음 충돌하는 하나의 물체만 감지하고, 트레이스 채널 정보를 통해 분별
GetWorld()->SweepSingleByChannel()
// ex.2
// 캐릭터 주위에 가상의 구체를 생성하고, 구체 안의 들어오는 물체를 감지
// 충돌하는 모든 물체를 배열로 받고 물체의 오브젝트 타입을 통해 분별
GetWorld()->OverlapMultiByObjectType()
트레이싱 함수 사용
SweepSingleByChannel 트레이스 함수를 사용하여 충돌 감지 구현을 해보자.
캐릭터의 시선 방향으로 가상의 구체를 투사하여 트레이스 채널이 적합한 충돌 물체를 반환
구현 단계
- 1. 충돌한 물체에 대한 결괏값을 저장할 FHitResult 구조체 선언
- 2. 트레이싱의 시작점과 끝점의 위치 구하기
- 3. 원하는 충돌 물체인지 분별할 트레이스 채널 정하기
- 4. 충돌 영억을 지정할 가상의 도형 정하기
FCollisionShape에서 제공하는 MakeSphere 함수를 사용하여 즉석으로 생성함 - 5. 충돌을 무시할 쿼리 파라미터 정하기, FCollisionParams 구조체를 사용한다.
첫 번째 인자 : 콜리전 분석에서 태그를 통해 분석할 때 식별자 정보로 사용
두 번째 인자 : 콜리전 분석을 복잡한 형태로 계산할지 여부
세 번째 인자 : 충돌을 무시할 물체 (보통 this를 넣음)
일반적으로 DefaultQueryParam으로 기본값 지정 후, 제외 대상에 자신을 추가하는 방식 사용 추천
void AABCharacterBase::Test()
{
// 충돌 결과를 저장할 구조체
FHitResult HitResult;
// 충돌 무시 대상을 지정할 쿼리 파라미터
FCollisionQueryParams Params = FCollisionQueryParams::DefaultQueryParam;
Params.AddIgnoredActor(this);
const float AttackRange = 40.f; // 공격 사거리
const float AttackRadius = 50.f; // 공격 반경
const float AttackDamage = 30.f; // 공격 피해량
// 트레이싱 시작점 : 캐릭터 위치 + (전방 방향 * 캡슐 반지름)
const FVector Start = GetActorLocation() + (GetActorForwardVector() * GetCapsuleComponent()->GetScaledCapsuleRadius());
// 트레이싱 끝점 : 시작점 + (전방 방향 * 공격 사거리)
const FVector End = Start + (GetActorForwardVector() * AttackRange);
bool HitDetected = GetWorld()->SweepSingleByChannel(
HitResult, // 충돌 결과를 저장할 변수
Start, // 트레이싱 시작 위치
End, // 트레이싱 끝 위치
FQuat::Identity, // 회전 정보 (없음)
ECC_GameTraceChannel1, // 트레이스 채널
FCollisionShape::MakeSphere(AttackRadius), // 충돌 영역 (구체)
Params); // 쿼리 파라미터
// 충돌 여부에 따라 디버그 구체를 그린다
if (HitDetected)
{
DrawDebugSphere(GetWorld(), End, AttackRadius, 8, FColor::Green, false, 5.f);
}
else
{
DrawDebugSphere(GetWorld(), End, AttackRadius, 8, FColor::Red, false, 5.f);
}
}
728x90
반응형