프로젝트 세팅 - 콜리전에서 오브젝트 채널, 트레이스 채널 및 프리셋을 지정해 줄 수 있다

오브젝트 채널: 콜리전 영역에 지정하는 콜리전 채널 (WorldStatic, WorldDynamic, Pawn, PhysicsBody 등)

트레이스 채널: 어떤 행동에 설정하는 콜리전 채널 (Visibility, Camera)

 

 

// MyAnimInstance.h
DECLARE_MULTICAST_DELEGATE(FOnAttackHit); // 델리게이트 타입 생성

UCLASS()
class TESTUNREALENGINE_API UMyAnimInstance : public UAnimInstance
{
public: // private으로 은닉해야 하지만 번거로우므로 public으로 열어둠
    FOnAttackHit OnAttackHit;
}

// MyAnimInstance.cpp
void UMyAnimInstance::AnimNotify_AttackHit()
{
    UE_LOG(LogTemp, Log, TEXT("AnimNotify_AttackHit"));
    // 노티파이 발생시 OnAttackHit을 구독하는 객체들에게 메시지를 뿌림
    OnAttackHit.Broadcast();
}

// ---------------

// MyCharacter.h
protected:
    // 생명주기상 BeginPlay보다는 모든 컴포넌트들이 초기화가 된 이후에
    // 서로 연동시켜주는 부분을 넣는것이 맞기 때문에 해당 함수 오버라이딩
    virtual void PostInitializeComponents() override;
public:
    void AttackCheck();

// MyCharacter.cpp
void AMyCharacter::PostInitializeComponents()
{
    Super::PostInitializeComponents();

    // 기존에 BeginPlay에 있던 내용들도 옮겨준다
    AnimInstance = Cast<UMyAnimInstance>(GetMesh()->GetAnimInstance());
    if (AnimInstance)
    {
        AnimInstance->OnMontageEnded.AddDynamic(this, &AMyCharacter::OnAttackMontageEnded);
        //OnAttackHit을 구독하여 Broadcast를 받을 때 실행할 메소드 등록
        AnimInstance->OnAttackHit.AddUObject(this, &AMyCharacter::AttackCheck);
    }
}

void AMyCharacter::AttackCheck()
{
	FHitResult HitResult;
	FCollisionQueryParams Params(NAME_None, false, this);

	float AttackRange = 100.f;
	float AttackRadius = 50.f;

	bool bResult = GetWorld()->SweepSingleByChannel(
		OUT HitResult, GetActorLocation(),
		GetActorLocation() + GetActorForwardVector() * AttackRange,
		FQuat::Identity,
		ECollisionChannel::ECC_GameTraceChannel2,
		FCollisionShape::MakeSphere(AttackRadius),
		Params);

	if (bResult && HitResult.Actor.IsValid())
	{
		UE_LOG(LogTemp, Log, TEXT("Hit Actor : %s"), *HitResult.Actor->GetName());
	}
}

 

노티파이가 발생할 때마다 OnAttackHit에 등록된(구독하는) MyCharacter의 AttackCheck가 실행되는데, 내부적으로 충돌 체크를 연산하여 실제로 충돌중일때만 로그를 띄우게 된다.

 

// MyCharacter.cpp
#include "DrawDebugHelpers.h"

FVector Vec = GetActorForwardVector() * AttackRange;
FVector Center = GetActorLocation() + Vec * 0.5f;
float HalfHeight = AttackRange * 0.5f + AttackRadius;
FQuat Rotation = FRotationMatrix::MakeFromZ(Vec).ToQuat();
FColor DrawColor;
if (bResult)
    DrawColor = FColor::Green;
else
    DrawColor = FColor::Red;

DrawDebugCapsule(GetWorld(), Center, HalfHeight, AttackRadius,
    Rotation, DrawColor, false, 2.f);

 

AttackCheck에 해당 내용을 추가로 넣어주면 시각적으로 공격의 실패, 성공 여부를 확인할 수 있다.

 

충돌 처리는 온갖 부분에서 다 쓰이므로 매우 중요한 내용이다.

+ Recent posts