Showing

[Unreal] 델리게이트를 활용하여 Bullet으로 enemy 제거 본문

Unreal

[Unreal] 델리게이트를 활용하여 Bullet으로 enemy 제거

RabbitCode 2023. 10. 24. 11:22

델리게이트는 A에 Function을 등록해두었다가, A가 불리면 등록해둔 Function을 호출할 수 있는 기능이다. 참고로,  Delegate 와 Function의 매개 변수 구성이 같아야 한다.

OnComponentBeginOverlap에 함수를 등록하여 총알이 enemy에 닿을 경우에 enemy를 제거하는 기능을 수행하도록 코드를 작성해보도록 한다.

OnComponentBeginOverlap  블루프린트

Delegate 와 Function의 매개 변수 구성이 같아야 하므로, 블루프린트를 참고하여도 되고 아니면

sphereComponent->OnComponentBeginOverlap 이렇게 코드를 작성하고 OnComponentBeginOverlap에 커서를 올려 f12를 누르면  C:\Program Files\Epic Games\UE_5.2\Engine\Source\Runtime\Engine\Classes\Components\PrimitiveComponent.h로 타고 들어가게 된다.

PrimitiveComponent.h 에서 OnComponentBeginOverlap를 전체 검색하면, 인자들을 찾아볼 수 있다.

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams( 
FComponentBeginOverlapSignature, UPrimitiveComponent, 
OnComponentBeginOverlap, UPrimitiveComponent*, 
OverlappedComponent, AActor*, OtherActor, 
UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, 
bFromSweep, const FHitResult &, SweepResult);

bullet.h 에 같은 인자구성을 한 UFUNCTION()를 만들어준다.

	UFUNCTION() //델리게이트에 붙일 함수 제작
		void OnBulletOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
			UPrimitiveComponent* OtherComp, int32 OhterBodyIndex, bool bFromSweep,
			const FHitResult& SweepResult);

bullet.cpp

sphereComp의 OnComponentBeginOverlap (델리게이트)와 OnBulletOverlap (함수)를 연결헤준다.

OnComponentBeginOverlap(사장님)가 ABullet::OnBulletOverlap(일꾼, 대리자)에게 일을 시키는 원리이다.

void ABullet::BeginPlay()
{
	Super::BeginPlay();

	//AddDynamic -> Dynamic 동적, bind
	sphereComponent->OnComponentBeginOverlap.AddDynamic(this, &ABullet::OnBulletOverlap);

}

//OnComponentBeginOverlap(사장님)가 ABullet::OnBulletOverlap(일꾼, 대리자)에게 일을 시킴

참고로, 블루프린트 cast는 상당히 성능이 좋지 않다. 따라서 웬만하면 형변환은 c++를 사용하는 것이 낫다.

만들어둔 OnBulletOverlap에서 필요한 내역들을 상세 코딩해준다.

void ABullet::OnBulletOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OhterBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	//OtherActor가 존재하는데 어떠한 Actor랑 Overlapped 함
	AEnemyActor* enemy = Cast<AEnemyActor>(OtherActor);
	//OtherActor를 AEnemy 클래스로 취급해서, (형변환)
	//enemy 주소에 넣어봄

	//만약에 enemy 주소가 비어있지 않다면,
	if (enemy != nullptr) {
		OtherActor->Destroy();
		//OtherActor는 enemy이다.
	}
}

총알에 부딪힌 enemy가 정상적으로 제거되는 것을 확인할 수 있다!