grab 함수 리팩토링
아웃 파라미터 활용
파라미터를 받아들이는 함수 생성
함수들을 작고 명확하게 분할
헤더파일에 노출 시켜주어야 함
작업 순서:
1. 시작과 끝 벡터 계산하여 히트 여부를 불리언 값으로 반환
2. grab 함수의 역할을 하는 if 문 유지
3. 리지드 바디를 활성화하고 컴포넌트를 집는 부분을 Grab 함수 내부로 이동
4. 그 외 유틸리티 함수 및 불필요한 부분 정리
함수 분리 전
void UGrabber::Grab()
{
UPhysicsHandleComponent *PhysicsHandle = GetPhysicsHandle();
// physicshandle이 nullptr일때 바로 리턴
if (PhysicsHandle == nullptr)
{
return;
}
FHitResult HitResult;
FVector Start = GetComponentLocation();
FVector End = Start + GetForwardVector() * MaxGrabDistance;
DrawDebugLine(GetWorld(), Start, End, FColor::Red);
DrawDebugSphere(GetWorld(), End, 10, 10, FColor::Blue, false, 5);
FCollisionShape Sphere = FCollisionShape::MakeSphere(GrabRadius);
bool HasHit = GetWorld()->SweepSingleByChannel(
HitResult,
Start, End,
FQuat::Identity,
ECC_GameTraceChannel2,
Sphere);
if (HasHit)
{
UPrimitiveComponent *HitComponent = HitResult.GetComponent();
HitComponent->WakeAllRigidBodies();
PhysicsHandle->GrabComponentAtLocationWithRotation(
HitComponent,
NAME_None,
HitResult.ImpactPoint,
GetComponentRotation());
}
}
함수 분리 후
void UGrabber::Grab()
{
UPhysicsHandleComponent *PhysicsHandle = GetPhysicsHandle();
// physicshandle이 nullptr일때 바로 리턴
if (PhysicsHandle == nullptr)
{
return;
}
FHitResult HitResult;
bool HasHit = GetGrabbableInReach(HitResult);
if (HasHit)
{
UPrimitiveComponent *HitComponent = HitResult.GetComponent();
HitComponent->WakeAllRigidBodies();
PhysicsHandle->GrabComponentAtLocationWithRotation(
HitComponent,
NAME_None,
HitResult.ImpactPoint,
GetComponentRotation());
}
}
bool UGrabber::GetGrabbableInReach(FHitResult& OutHitResult) const
{
FVector Start = GetComponentLocation();
FVector End = Start + GetForwardVector() * MaxGrabDistance;
DrawDebugLine(GetWorld(), Start, End, FColor::Red);
DrawDebugSphere(GetWorld(), End, 10, 10, FColor::Blue, false, 5);
FCollisionShape Sphere = FCollisionShape::MakeSphere(GrabRadius);
return GetWorld()->SweepSingleByChannel(
OutHitResult,
Start, End,
FQuat::Identity,
ECC_GameTraceChannel2,
Sphere);
}