DoDefaultAttack() 함수에서 실제 공격 판정 Sphere와 DrawDebugCapsule에서 그리는 Capsule의 형태가 일치 X
- 실제 공격판정인 SweepSingleByChannel에서는 FQuat::Identity를 사용해 스피어가 Z축 기준으로 수직으로 서있는 형태이고 DrawDebugCapsule에서는 FQuat Rotation = FRotationMatrix::MakeFromZ(Vec).ToQuat() 변수를 선언한뒤 Rotaion을 적용하여 캐릭터의 정면 방향으로 그리게 되는 것을 FQuat Rot = FRotationMatrix::MakeFromZ(EndPos - StartPos).ToQuat(); 를 공통으로 사용하여 일치하게 수정
void ACOECharacter::DoDefaultAttack()
{
FHitResult HitResult;
FCollisionQueryParams Params;
Params.AddIgnoredActor(this);
Params.bTraceComplex = false;
Params.bReturnPhysicalMaterial = false;
float AttackRange = 250.f;
float AttackRadius = 50.f;
FVector StartPos = GetActorLocation();
FVector EndPos = GetActorLocation() + GetActorForwardVector() * AttackRange;
FQuat Rot = FRotationMatrix::MakeFromZ(EndPos - StartPos).ToQuat(); // 수정을 위해 추가된 부분
bool Result = GetWorld()->SweepSingleByChannel
(
HitResult,
StartPos,
EndPos,
Rot, //FQuat::Identity에서 미리 선언한 Rot으로 수정
ECC_GameTraceChannel3,
FCollisionShape::MakeSphere(AttackRadius),
Params
);
FVector Center = (StartPos + EndPos) * 0.5f;
float HalfHeight = AttackRange * 0.5f;
//FQuat Rotation = FRotationMatrix::MakeFromZ(Vec).ToQuat(); -> 같은 FQuat Rot을 사용하기 위해 삭제
FColor DrawColor;
DrawColor = Result ? FColor::Green : FColor::Red;
//실제 공격에 사용한 FQuat값을 사용하기위해 기존의 Rotation 대신 Rot을 사용
DrawDebugCapsule(GetWorld(), Center, HalfHeight, AttackRadius, Rot, DrawColor, false, 2.f);
if (Result && HitResult.GetActor())
{
UE_LOG(LogTemp, Log, TEXT("Hit : %s"), *HitResult.GetActor()->GetName());
UGameplayStatics::ApplyDamage(HitResult.GetActor(), 10.f, GetInstigatorController(), this, nullptr);
if (AExplorationEnemy* Enemy = Cast<AExplorationEnemy>(HitResult.GetActor()))
{
if (Enemy->PossibleBattleLevels.Num() > 0)
{
FName SelectedBattleMap = Enemy->PossibleBattleLevels[FMath::RandRange(0, Enemy->PossibleBattleLevels.Num() - 1)];
if (UCOEGameInstance* GI = Cast<UCOEGameInstance>(UGameplayStatics::GetGameInstance(this)))
{
GI->bPlayerInitiative = true;
GI->bPlayerWasDetected = false;
GI->ReturnLocation = GetActorLocation();
GI->ReturnMapName = FName("Lvl_ThirdPerson");
GI->EnemyToRemove = HitResult.GetActor();
}
UGameplayStatics::OpenLevel(this, SelectedBattleMap);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Enemy has no PossibleBattleLevels!"));
}
}
}
UE_LOG(LogTemp, Warning, TEXT("DefaultAttack() called in TurnBattleLevel!"));
}
DetectPlayerComponent.cpp 구현 중 생성자에 스피어 반경, CollisionProfile 설정, Bind overlap Event 등을 구현하였더니 컴파일이 안되는 오류 발생
- 생성자에서 구현 X BeginPlay에서 구현하여 CollsionProfile 시스템이 완전히 초기화 된 이후 안전하게 적용
// 초기 작성 코드
UDetectPlayerComponent::UDetectPlayerComponent()
{
// 충돌 반경설정
SetSphereRadius(100.f);
SetCollisionProfileName(TEXT("OverlapAllDynamic"));
// Bind overlap events
OnComponentBeginOverlap.AddDynamic(this, &UDetectPlayerComponent::HandleBeginOverlap);
OnComponentEndOverlap.AddDynamic(this, &UDetectPlayerComponent::HandleEndOverlap);
}
void UDetectPlayerComponent::BeginPlay()
{
Super::BeginPlay();
}
// 수정 코드
UDetectPlayerComponent::UDetectPlayerComponent()
{
}
void UDetectPlayerComponent::BeginPlay()
{
Super::BeginPlay();
// 충돌 반경설정
SetSphereRadius(100.f);
SetCollisionProfileName(TEXT("OverlapAllDynamic"));
// Bind overlap events
OnComponentBeginOverlap.AddDynamic(this, &UDetectPlayerComponent::HandleBeginOverlap);
OnComponentEndOverlap.AddDynamic(this, &UDetectPlayerComponent::HandleEndOverlap);
}