728x90
반응형
물체의 충돌을 감지하는 방법 중 가장 대표적으로 트레이싱 함수가 있다.
트레이싱 함수는 언리얼에서 제공하는 일반적인 트레이싱 함수와 Kismet 라이브러리에서 제공하는 함수가 있다.
일반 트레이싱 함수
먼저 일반 트레이싱 함수에 대해 알아보자.
일반 트레이싱 함수의 이름은 세 가지 카테고리의 이름을 붙여 결정된다.
함수명
1. 트레이싱 방법
- LineTrace : 지정한 방향으로 선을 투사하여, 이 선이 물체와 충돌하는지 감지한다.
- Sweep : 선이 아닌 도형(구체, 박스 등)을 투사하여 충돌을 감지한다.
- Overlap : 지정한 영역(구체, 박스 등) 내에 충돌하는 물체가 있는지 감지한다.
2. 트레이싱 대상
- Test : 충돌 여부를 단순히 테스트하여 반환한다.
- Single : 충돌이 감지된 단일 물체에 대한 정보를 반환한다.
- Multi : 충돌이 감지된 모든 물체의 정보를 배열로 반환한다.
LineTrace와 Sweep의 경우 Single이 붙는다.
Overlap의 경우 AnyTest가 붙는다.
3. 트레이싱 설정
- ByChannel : 물체의 트레이스 채널 정보를 사용하여 충돌 대상을 감지한다.
- ByProfile : 물체의 콜리전 프로필 정보를 사용하여 충돌 대상을 감지한다.
- ByObjectType : 물체의 오브젝트 타입을 사용하여 충돌 대상을 감지한다.
GetWorld()->LineTraceSingleByChannel();
GetWorld()->LineTraceSingleByProfile();
GetWorld()->LineTraceSingleByObjectType();
GetWorld()->LineTraceMultiByChannel();
GetWorld()->LineTraceMultiByProfile();
GetWorld()->LineTraceMultiByObjectType();
GetWorld()->SweepSingleByChannel();
GetWorld()->SweepSingleByProfile();
GetWorld()->SweepSingleByObjectType();
GetWorld()->SweepMultiByChannel();
GetWorld()->SweepMultiByProfile();
GetWorld()->SweepMultiByObjectType();
GetWorld()->OverlapAnyTestByChannel();
GetWorld()->OverlapAnyTestByProfile();
GetWorld()->OverlapAnyTestByObjectType();
GetWorld()->OverlapBlockingTestByChannel();
GetWorld()->OverlapBlockingTestByProfile();
GetWorld()->OverlapMultiByChannel();
GetWorld()->OverlapMultiByProfile();
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);
}
}
Kismet 트레이싱 함수
다음으로 Kismet 라이브러리의 트레이싱 함수에 대해 알아보자.
여기도 일반 트레이싱 함수와 같이, 트레이싱 함수의 이름은 세 가지 카테고리의 이름을 붙여 결정된다.
함수명
1. 트레이싱 방법
- Line: 지정한 방향으로 선을 생성하고, 이 선과 충돌하는 물체가 있는지 검사한다.
- Box: 지정한 방향으로 하나의 박스를 생성하고, 이 박스 경계 안에 충돌하는 물체가 있는지 검사한다.
- Sphere: 지정한 방향으로 하나의 구체를 생성하고, 이 구체 경계 안에 충돌하는 물체가 있는지 검사한다.
- Capsule: 지정한 방향으로 하나의 캡슐을 생성하고, 이 캡슐 경계 안에 충돌하는 물체가 있는지 검사한다.
2. 트레이싱 대상
- Single: 충돌이 감지된 단일 물체에 대한 정보를 반환한다.
- Multi: 충돌이 감지된 모든 물체의 정보를 배열로 반환한다.
3. 트레이싱 조건
- By Channel: 물체의 트레이스 채널 정보를 사용하여 충돌 대상을 감지한다.
- By Profile: 물체의 콜리전 프로필 정보를 사용하여 충돌 대상을 감지한다.
- For Objects: 물체의 오브젝트 타입을 사용하여 충돌 대상을 감지한다.
UKismetSystemLibrary::LineTraceSingle();
UKismetSystemLibrary::LineTraceSingleByProfile();
UKismetSystemLibrary::LineTraceSingleForObjects();
UKismetSystemLibrary::LineTraceMulti();
UKismetSystemLibrary::LineTraceMultiByProfile();
UKismetSystemLibrary::LineTraceMultiForObjects();
UKismetSystemLibrary::BoxTraceSingle();
UKismetSystemLibrary::BoxTraceSingleByProfile();
UKismetSystemLibrary::BoxTraceSingleForObjects();
UKismetSystemLibrary::BoxTraceMulti();
UKismetSystemLibrary::BoxTraceMultiByProfile();
UKismetSystemLibrary::BoxTraceMultiForObjects();
UKismetSystemLibrary::SphereTraceSingle();
UKismetSystemLibrary::SphereTraceSingleByProfile();
UKismetSystemLibrary::SphereTraceSingleForObjects();
UKismetSystemLibrary::SphereTraceMulti();
UKismetSystemLibrary::SphereTraceMultiByProfile();
UKismetSystemLibrary::SphereTraceMultiForObjects();
UKismetSystemLibrary::CapsuleTraceSingle();
UKismetSystemLibrary::CapsuleTraceSingleByProfile();
UKismetSystemLibrary::CapsuleTraceSingleForObjects();
UKismetSystemLibrary::CapsuleTraceMulti();
UKismetSystemLibrary::CapsuleTraceMultiByProfile();
UKismetSystemLibrary::CapsuleTraceMultiForObjects();
트레이싱 함수 사용
#include "Kismet/KismetSystemLibrary.h"
void AABCharacterBase::Test()
{
// 충돌 감지 배열
TArray<FHitResult> HitResults;
// 박스 트레이스 충돌 길이
float BoxTraceDistance = 2000.0f;
// 박스 트레이스 크기
FVector TraceBoxSize = FVector(500.0f, 750.0f, 1500.0f);
// 충돌 감지 채널
TArray<TEnumAsByte<EObjectTypeQuery>> BoxTraceChannel;
// 디버깅 여부
bool bShowPersistentDebugShape = false;
// 충돌 무시할 액터
TArray<AActor*> ActorsToIgnore;
ActorsToIgnore.AddUnique(this);
const FVector Start = GetActorLocation();
const FVector End = GetActorLocation() + GetActorForwardVector() * BoxTraceDistance;
// 트레이싱 함수 (박스 형태를 투사하여 오버랩되는 모든 오브젝트를 감지)
UKismetSystemLibrary::BoxTraceMultiForObjects(
this,
Start, // 트레이싱 시작 위치
End, // 트레이싱 끝 위치
TraceBoxSize / 2.0f, // 트레이싱 반지름
GetActorForwardVector().ToOrientationRotator(), // 트레이싱 방향
BoxTraceChannel, // 트레이싱 채널
false,
ActorsToIgnore, // 충돌 무시 배열
bShowPersistentDebugShape ? EDrawDebugTrace::Persistent : EDrawDebugTrace::None,
HitResults, // 충돌 결과를 저장할 변수
true // 트레이싱에 본인 포함 여부
);
}
728x90
반응형
'📘Unreal Engine > 📝Unreal Engine' 카테고리의 다른 글
| [Unreal Engine] 가장 근접한 대상 찾기 (0) | 2024.11.11 |
|---|---|
| [Unreal Engine] 비헤이비어 트리(Behavior Tree) 구조 (0) | 2024.08.19 |
| [Unreal Engine] 강 참조와 약 참조 (Hard and Soft Reference) (0) | 2024.08.05 |
| [Unreal Engine] 캐릭터 컨트롤 옵션 (0) | 2024.07.25 |
| [Unreal Engine] 입력 시스템 / 향상된 입력 시스템 (Enhanced Input System) (0) | 2024.07.24 |