Home [UE] 충돌 체크 - OnComponentBeginOverlap vs NotifyActorBeginOverlap
Post
Cancel

[UE] 충돌 체크 - OnComponentBeginOverlap vs NotifyActorBeginOverlap

언리얼 엔진에서 Overlap 기능으로 OnComponentBeginOverlap 방식과 NotifyActorBeginOverlap 방식이 있는데

둘 다 특정 객체가 Overlap 되었을 때 체크를 해주는 기능이다.

사용 방법을 먼저 확인해 보면 NotifyActorBeginOverlap  경우는 아래와 같다.

1. 사용 방법

NotifyActorBeginOverlap

header file

1
2
3
4
5
6
7
8
9
UCLASS()
class TPS_PROTOTYPE_API AARBullet : public AActor
{
	GENERATED_BODY()
protected:
	virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;
	virtual void NotifyActorEndOverlap(AActor* OtherActor) override;

};

cpp file

1
2
3
4
5
6
7
8
9
void AARBullet::NotifyActorBeginOverlap(AActor* OtherActor)
{
	GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Yellow, FString::Printf(TEXT("Notify Actor Begin Overlap... Other Actor Name: %s"), *OtherActor->GetName()));
}

void AARBullet::NotifyActorEndOverlap(AActor* OtherActor)
{
	GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Blue, FString::Printf(TEXT("Notify Actor End Overlap... Other Actor Name: %s"), *OtherActor->GetName()));
}

OnComponentBeginOverlap

header file

1
2
3
4
5
6
7
8
9
10
11
12
13
UCLASS()
class TPS_PROTOTYPE_API AARBullet : public AActor
{
	GENERATED_BODY()
protected:
	/** Overlap Begin */
	UFUNCTION()
	void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

	/** Overlap End */
	UFUNCTION()
	void OnOverlapEnd(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
};

cpp file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Sets default values
AARBullet::AARBullet()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	StaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
	SetRootComponent(StaticMeshComponent);

	// AddDynamic을 통해 함수를 바인딩해준다.
	StaticMeshComponent->OnComponentBeginOverlap.AddDynamic(this, &AARBullet::OnOverlapBegin);
	StaticMeshComponent->OnComponentEndOverlap.AddDynamic(this, &AARBullet::OnOverlapEnd);
}

void AARBullet::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Blue, FString::Printf(TEXT("On Overlap Begin... Other Actor Name: %s"), *OtherActor->GetName()));
}

void AARBullet::OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Blue, FString::Printf(TEXT("On Overlap End... Other Actor Name: %s"), *OtherActor->GetName()));
}

2. 차이점

NotifyActorBeginOverlap 함수는 위 코드를 보다시피 가상함수를 오버라이딩해서 재사용하고 있다.

즉, AActor 클래스에 가상 함수로 정의가 되어 있는 함수임으로 Actor만 사용이 가능한 함수이다.

이와 다르게,

OnComponentBeginOverlap는 PrimitiveComponent.h 에 변수로 정의되어 있다.

1
2
3
4
5
6
7
8
9
10
/** 
 *	Event called when something starts to overlaps this component, for example a player walking into a trigger.
 *	For events when objects have a blocking collision, for example a player hitting a wall, see 'Hit' events.
 *
 *	@note Both this component and the other one must have GetGenerateOverlapEvents() set to true to generate overlap events.
 *	@note When receiving an overlap from another object's movement, the directions of 'Hit.Normal' and 'Hit.ImpactNormal'
 *	will be adjusted to indicate force from the other object against this object.
 */
UPROPERTY(BlueprintAssignable, Category="Collision")
FComponentBeginOverlapSignature OnComponentBeginOverlap;

그렇기 때문에 Actor가 아니더라도 Overlap 충돌 체크를 할 수 있다.

3. “OnComponentBeginOverlap”에 바인딩하는 함수는 왜 파라미터 값이 고정된 걸까?

OnComponentBeginOverlapOnComponentEndOverlap 둘 다
AddDynamic을 통해 함수를 바인딩해줄 수 있다.

이 때 바인딩할 함수의 파라미터 값들은 아래와 같이 고정되어 있는데

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/** Begin Overlap */
void AARBullet::OnOverlapBegin(
	UPrimitiveComponent* OverlappedComp, 
	AActor* OtherActor, 
	UPrimitiveComponent* OtherComp, 
	int32 OtherBodyIndex, 
	bool bFromSweep, 
	const FHitResult& SweepResult)
{
}

/** End Overlap */
void AARBullet::OnOverlapEnd(
	UPrimitiveComponent* OverlappedComp, 
	AActor* OtherActor, 
	UPrimitiveComponent* OtherComp, 
	int32 OtherBodyIndex)
{

}

이는 OnComponentBeginOverlapOnComponentEndOverlap델리게이트 형식으로 선언된 변수이기 때문이다.

예를 들어, OnComponentBeginOverlap의 선언부를 확인해보면 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
 // PrimitiveComponent.h

 /** 
 *	Event called when something starts to overlaps this component, for example a player walking into a trigger.
 *	For events when objects have a blocking collision, for example a player hitting a wall, see 'Hit' events.
 *
 *	@note Both this component and the other one must have GetGenerateOverlapEvents() set to true to generate overlap events.
 *	@note When receiving an overlap from another object's movement, the directions of 'Hit.Normal' and 'Hit.ImpactNormal'
 *	will be adjusted to indicate force from the other object against this object.
 */
UPROPERTY(BlueprintAssignable, Category="Collision")
FComponentBeginOverlapSignature OnComponentBeginOverlap;

코드를 보면 FComponentBeginOverlapSignature라는 자료형으로 선언되어 있는데 FComponentBeginOverlapSignature의 선어부를 보면 델리게이트로 선언되어 있음을 알 수 있다.

1
2
/** Delegate for notification of start of overlap with a specific component */
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams( FComponentBeginOverlapSignature, UPrimitiveComponent, OnComponentBeginOverlap, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);

즉,
OnComponentBeginOverlap델리게이트로 선언되어 있기 때문에
바인딩할 함수의 파라미터 값은 델리게이트 선언 방식에 맞춰서 해주어야 한다.

This post is licensed under CC BY 4.0 by the author.