필요한 개념
충돌 정의 : Sparse Dynamic Delegate로 이루어짐
ActorBeginOverlap? 충돌하려는 각 액터에 충돌체가 최소한 하나 이상 존재, 해당 충돌체는 Generate Overlap 이벤트가 켜져 있어야 수행
BP_CPlayer BP를 보면 ActorBeginOverlap 이벤트가 있다.(Actor로 부터 상속받는 애들은 다 가짐)
ActorBeginOverlap 이벤트 : 델리게이트 이벤트이다.(정확히는 델리게이트와 이벤트는 다름), 둘다 엄연히 어떤 특정한 상황에 호출됨
타킷은 Actor(부모)에 정의되어 있다고 나옴
항상 델리게이트나 이벤트의 함수명은 On으로 시작함
OnActorBeginOverlap
Sparse Delegate는 너무 까다로워서 정의하지 않고(잘 안씀) Dynamic Multicast까지만 갈 것이다.
// AddDynamic으로 다이나믹 델리게이트로 하는 거라서 Dynamic으로 등록함
// 1 : 어느객체에 있는 함수 호출할건지 2 : 함수의 주소
// 일반 델리게이트는 파라미터의 순서와 타입이 일치하면 되지만
// 다이나믹 델리게이트는 파라미터의 순서와 타입과 이름까지도 모두 일치해야함
// OnActorBeginOverlap는 FActorBeginOverlapSignature으로 정의가 되어있는데
// 들어가 보면 아래 매크로로 정의되어 있는데
// 1 : 델리게이션의 자료형 2 : 델리게이션의 소속된 클래스 3 : 델리게이션의 소속된 이름, 4,5 : 델리게이트가 연결될 파라미터
// 즉 다이나믹 델리게이트는 AActor* OverlappedActor AActor*, OtherActor에서 타입과 이름이 정확히 일치해야함
// DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams( FActorBeginOverlapSignature, AActor, OnActorBeginOverlap, AActor*, OverlappedActor, AActor*, OtherActor );
// Overlap이 되면 파라미터를 넣어준 함수를 콜함
OnActorBeginOverlap.AddDynamic(this, &AC01_ActorBeginOverlap::ActorBeginOverlap);
// 다이나믹 델리게이트여서 파라미터의 타입과 이름이 일치해야함
// 델리게이션에 의해 콜될 함수는 반드시 UFUNCTION()을 붙여줘야 한다.
// UFUNCTION() : 언리얼 에디터나 BP와 통신할 수 있는 함수
// 델리게이트가 BP와 통신할 일이 생기니까 UFUNTION()을 붙여준다고 일단 생각하라
UFUNCTION()
void ActorBeginOverlap(AActor* OverlappedActor, AActor* OtherActor);
결과를 보면 충돌 되었다고 뜬다.
이런식으로 ActorBeginOverlap을 정의할 수 있다.
델리게이션 종류
- 기본 델리게이션 : C내부에서만 쓸 수 있음(C++ 내부에서만 서로 간의 콜할시)
- 다이나믹 델리게이션 : C++에서 콜하고 BP에서 사용, C++에서 콜가능하고 BP에서도 콜 가능(필요하다면 BP에서도 정의할 수 있음), BP에서 델리게이션 또 정의하면 BP에 있는 것도 콜되고, C의 것도 콜이 된다.
- 이벤트 델리게이션 : 델리게이션이 정의된 클래스에서만 가능(일단은 그렇구나 하고 넘어가자)
결과를 보면 C에서 정의한 것 메세지도 출력이되고 BP에서 정의한 것도 화면 메세지에 출력된다.
즉, 다이나믹 델리게이션은
이런식으로 C에서 정의된 델리게이트를 BP에서도 콜할 수가 있음
문제 : 텍스트에 Default가 뜬다?
BP로 만들면 그렇게 됨, C에서 BeginPlay()에서 UTextRenderComponent변수 Text->Text() 해서 이름 바꿔놓으면 됨
ActorBeginOverlap이 일어날 수 있는 조건
1. 충돌하려는 액터당 1개의 충돌체가 있어야함
2. 서로의 각 충돌체의 Generate Overlap Events가 켜져있어야함
Tip)
BP에서 OnActorEndOverlap에 이벤트 바인딩은 기본으로 한개로 연결할 수 있도록 되어있고
OnActorEndOverlap 할당은 여러개를 연결할 수 있다.
항상 델리게이션은 F12로 파고 들어서 부모 매크로 까지 본다음 어떤 파라미터를 받아야 하는지 체크해야 한다.
C01_ActorBeginOverlap.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C01_ActorBeginOverlap.generated.h"
UCLASS()
class UONLINE_03_CPP_API AC01_ActorBeginOverlap : public AActor
{
GENERATED_BODY()
private:
// 컴포넌트를 3개 넣어놈
// USceneComponent : 부모 자식 관계를 정의할 수 있는 Transform만 소유한 컴포넌트
UPROPERTY(VisibleDefaultsOnly)
class USceneComponent* Scene;
// 충돌체를 정의할
UPROPERTY(VisibleDefaultsOnly)
class UBoxComponent* Box;
// 텍스트 렌더링하는 역할 컴포넌트
UPROPERTY(VisibleDefaultsOnly)
class UTextRenderComponent* Text;
public:
AC01_ActorBeginOverlap();
protected:
virtual void BeginPlay() override;
private:
// 다이나믹 델리게이트여서 파라미터의 타입과 이름이 일치해야함
// 델리게이션에 의해 콜될 함수는 반드시 UFUNCTION()을 붙여줘야 한다.
// UFUNCTION() : 언리얼 에디터나 BP와 통신할 수 있는 함수
// 델리게이트가 BP와 통신할 일이 생기니까 UFUNTION()을 붙여준다고 일단 생각하라
UFUNCTION()
void ActorBeginOverlap(AActor* OverlappedActor, AActor* OtherActor);
UFUNCTION()
void ActorEndOverlap(AActor* OverlappedActor, AActor* OtherActor);
};
C01_ActorBeginOverlap.cpp
#include "C01_ActorBeginOverlap.h"
#include "Global.h"
#include "Components/BoxComponent.h" // SceneComponent는 Box에 대한 부모여서 헤더를 물고들어와서 인클루드 안해도됨
#include "Components/TextRenderComponent.h"
AC01_ActorBeginOverlap::AC01_ActorBeginOverlap()
{
// 부모가 될 컴포넌트
CHelpers::CreateComponent<USceneComponent>(this, &Scene, "Scene");
// 밑에 둘은 Scene가 부모가 됨
CHelpers::CreateComponent<UBoxComponent>(this, &Box, "Box", Scene);
CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Text", Scene);
// 이렇게 하면 x,y,z에 3이 모두 들어감
Box->SetRelativeScale3D(FVector(3));
// 지역변수 있으면 지역변수 쓰는 게 좋음(Set() 보다)
// Set()이 기본값으로 안먹히는 경우가 있다. 지역변수 있다면 지역변수가 낫다.
Box->bHiddenInGame = false;
// 에디터 세팅한대로 그대로 잡아줌
Text->SetRelativeLocation(FVector(0, 0, 100));
Text->SetRelativeRotation(FRotator(0, 180, 0));
// 다 2배 잡아줌
Text->SetRelativeScale3D(FVector(2));
Text->TextRenderColor = FColor::Red;
// 우리 BP에서 맨날 가운데 잡던거
Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;
// 객체의 이름으로
// FString -> FText
Text->Text = FText::FromString(GetName());
}
void AC01_ActorBeginOverlap::BeginPlay()
{
Super::BeginPlay();
// AddDynamic으로 다이나믹 델리게이트로 하는 거라서 Dynamic으로 등록함
// 1 : 어느객체에 있는 함수 호출할건지 2 : 함수의 주소
// 일반 델리게이트는 파라미터의 순서와 타입이 일치하면 되지만
// 다이나믹 델리게이트는 파라미터의 순서와 타입과 이름까지도 모두 일치해야함
// OnActorBeginOverlap는 FActorBeginOverlapSignature으로 정의가 되어있는데
// 들어가 보면 아래 매크로로 정의되어 있는데
// 1 : 델리게이션의 자료형 2 : 델리게이션의 소속된 클래스 3 : 델리게이션의 소속된 이름, 4,5 : 델리게이트가 연결될 파라미터
// 즉 다이나믹 델리게이트는 AActor* OverlappedActor AActor*, OtherActor에서 타입과 이름이 정확히 일치해야함
// DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_TwoParams( FActorBeginOverlapSignature, AActor, OnActorBeginOverlap, AActor*, OverlappedActor, AActor*, OtherActor );
// Overlap이 되면 파라미터를 넣어준 함수를 콜함
OnActorBeginOverlap.AddDynamic(this, &AC01_ActorBeginOverlap::ActorBeginOverlap);
OnActorEndOverlap.AddDynamic(this, &AC01_ActorBeginOverlap::ActorEndOverlap);
}
void AC01_ActorBeginOverlap::ActorBeginOverlap(AActor* OverlappedActor, AActor* OtherActor)
{
FString str = "";
str.Append("C++ Actor Begin Overlap :");
str.Append(OtherActor->GetName());
CLog::Log(str);
}
void AC01_ActorBeginOverlap::ActorEndOverlap(AActor* OverlappedActor, AActor* OtherActor)
{
FString str = "";
str.Append("C++ Actor End Overlap :");
str.Append(OtherActor->GetName());
CLog::Log(str);
}
결과
BP로는 PrintString()으로 화면과 출력로그에 띄우고 C에서는 출력로그에 띄운 각각의 델리게이트가 실행된 것을 볼 수 있다.
Dynamic 델리게이트여서 C와 BP에서 각 세팅이 가능하다.
'Unreal Engine 4 > C++' 카테고리의 다른 글
<Unreal C++> 15 - Delegate (0) | 2022.04.07 |
---|---|
<Unreal C++> 14 - Component Begin & End Overlap (0) | 2022.04.07 |
<Unreal C++> 12 - DrawDebug (0) | 2022.04.07 |
<Unreal C++> 11 - Debug(출력로그, 게임창) (0) | 2022.04.07 |
<Unreal C++> 10 - UAnimInstance (0) | 2022.04.07 |