언리얼 엔진에서 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”에 바인딩하는 함수는 왜 파라미터 값이 고정된 걸까?
OnComponentBeginOverlap
, OnComponentEndOverlap
둘 다
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)
{
}
이는 OnComponentBeginOverlap
, OnComponentEndOverlap
가 델리게이트 형식으로 선언된 변수이기 때문이다.
예를 들어, 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
는 델리게이트로 선언되어 있기 때문에
바인딩할 함수의 파라미터 값은 델리게이트 선언 방식에 맞춰서 해주어야 한다.