본문 바로가기

언리얼엔진/C++슈팅프로젝트제작

UE5 충돌이벤트와 델리게이트

충돌 조건을 설정했으니 충돌이 일어나면 실행될 함수를 마련해야 합니다. 이벤트가 발생되었을때 미리 만들어 놓은 함수를 실행하면서 매개변수에 자동으로 값을 넘겨주는 기능을 델리게이트라고 합니다. 델리게이트로 연결된 함수의 매개변수에 값을 전달하기 위해서는 함수의 매개변수의 자료형과 개수가 델리게이트에서 설정한 것과 동일해야 합니다. 

자세한건 이곳을 참조해주세요

2023.10.25 - [언리얼레퍼런스/언리얼 참조사이트] - Delegate

구현을 위해 Bullet.cpp의 BeginPlay()에 boxComp->OnComponentBeginOverlap을 추가하고 커서를 함수명에 올려놓고  F12를 눌러봅니다.

void ABullet::BeginPlay()
{
	Super::BeginPlay();
	boxComp->OnComponentBeginOverlap
	
}

그럼 정의로 이동하는데 

FComponentBeginOver lapSignature OnComponentBeginOverlap;

 

FComponentBeginOver위에서 F12를 눌러 이동하면 복잡한 화면이 나오는데 SixParams( 뒤에 파라미터가 6개 입니다. 이 자료형과 변수가 함수의 매개변수가 되어야 합니다.

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams( FComponentBeginOverlapSignature,

UPrimitiveComponent* 이하 const FHitResult& SweepResult까지 카피해 놓습니다.

UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, 
                        int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult

Bullet.h public:에 함수를 정의하고 복사한 파라미터를 붙여 넣습니다.

	UFUNCTION()
	void OnBulletOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, 
    					int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

Bullet.cpp에 함수를 구현합니다. 

EnemyActor.h를 추가해줍니다.

#include "EnemyActor.h"

Bullet.cpp BeginPlay()함수내 박스컴포넌트의 충돌 오버랩 이벤트에 BulletOverlap함수를 연결합니다.

void ABullet::BeginPlay()
{
	Super::BeginPlay();
	//박스컴포넌트의 충돌 오버랩 이벤트에 BulletOverlap함수를 연결합니다.
	boxComp->OnComponentBeginOverlap.AddDynamic(this, &ABullet::OnBulletOverlap);
}

충돌이벤트가 발생할때 실행할 함수

충돌된 Actor를 확인하기 위해 UE_LOG를 추가하였다 FString객체는 앞에 *를 붙여줘야 에러가 없음

충돌된  Actor를 AEnemyActor로 캐스트해서 문제가 없다면 OtherActor->Destroy() 해준다. 이후 자신도 Destroy()해준다

void ABullet::OnBulletOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, 
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	AEnemyActor* enemy = Cast<AEnemyActor>(OtherActor);
	UE_LOG(LogTemp, Display, TEXT("OtherActor is %s"), *enemy->GetActorNameOrLabel());
	if (enemy != nullptr)
		OtherActor->Destroy();
	Destroy();
}

 

에너미도 플레이어랑 충돌 처리를 하기 위해 Bullet.h의 OnBulletActorOverlap 선언을 복사해서 EnemyActor.h 에 복사하고 이름을 바꿔줍니다.

UFUNCTION()
void OnEnemyActorOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, 
    UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

EnemyActor.cpp 의 BeginPlay()에 EnemyOverlap함수를 연결해줍니다. 연결할 함수명은 AEnemyActor로 변경합니다.

	//박스컴포넌트의 충돌 오버랩 이벤트에 EnemyOverlap함수를 연결합니다.
	boxComp->OnComponentBeginOverlap.AddDynamic(this, &AEnemyActor::OnEnemyOverlap);

EnemyActor.cpp에 OnEnmeyOverlap()을 추가해 줍니다. PlayerPawn은  Other를 PlayerPawn으로 캐스트해서 nullPtr이 아니면 지워줍니다. 지은후 자기 자신도 같이 지워줍니다.

void AEnemyActor::OnEnemyOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, 
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	APlayerPawn* player = Cast<APlayerPawn>(OtherActor);
	UE_LOG(LogTemp, Display, TEXT("OtherActor is %s"), *player->GetActorNameOrLabel());
	if (player != nullptr)
		OtherActor->Destroy();
	Destroy();
}