[Unreal]#21_Custom Delegate

2022. 11. 2. 20:44· 게임개발/Unreal C++
목차
  1.  
  2. [Unreal]#21_Custom Delegate 

 

[Unreal]#21_Custom Delegate 

 

Unreal 개발 중 "Custom Delegate"에 대해 알아보겠습니다.

커스텀 대리자 함수 시그니처 생성 방법에 대해 살펴보겠습니다.

 


 

Custom Delegate Signature

1. 코드

DECLARE_DELEGATE(DELEGATE_NAME); //void  __(void)
DECLARE_DELEGATE_RetVal_OneParam(DELEGATE_RETURN_TYPE, DELEGATE_NAME, PARAM_1_RETURN_TYPE);

 

Delegate

1. 기본 구조

	// Delegate 활용 기본 구조
    
  	<Class 1>
	L1. DECLARE_DELEGATE : Custom Delegate Signature 메크로 생성
	L2. Custom Delegate 선언
	
	-------------- 어느 클래스라도 호출이 가능한 부분

	L3. IsBound() : Custom Delegate와 Binding된 함수가 존재하는지 체크
	L4. Execute() : Custom Delegate와 Binding된 함수에게 인자들을 넘겨주고, 함수 대리자 실행

	************************************************************************************************
	<Class 2>
	L1. CustomDeleagte와 Signature가 같은 사용자 정의 함수생성
	L2. CustomDelegate.BindFunction or AddUFunction 을 통해 Binding을 수행합니다.

	* Custom Deleagte 선언 클래스 혹은 Delegate의 바인딩을 수행하는 클래스에서 IsBound 체크 및 실행
	* Custom Delegate를 반는 측에서 동일한 Delegate Signature를 갖는 함수 생성 및 Binding 수행

 

코드 예제

1. ActorBeginOverlap.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C01_ActorBeginOverlap.generated.h"

UCLASS()
class U03_CPP_API AC01_ActorBeginOverlap : public AActor
{
	GENERATED_BODY()
	
private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Scene;

	UPROPERTY(VisibleDefaultsOnly)
		class UBoxComponent* Box;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC01_ActorBeginOverlap();

protected:
	virtual void BeginPlay() override;

private:
	// FActorBeginOverlapSignature
	UFUNCTION()
		void ActorBeginOverlap(AActor* OverlappedActor, AActor* OtherActor);
	
   	 // FActorEndOverlapSignature
	UFUNCTION()
		void ActorEndOverlap(AActor* OverlappedActor, AActor* OtherActor);
};
  1. 대리자 함수와 바인딩되는 함수는 같은 함수 시그니처를 가져야합니다!
  2. FActorBeginOverlapSignature(제공 시그니처)와 동일한 함수 시그니처를 갖는 ActorBeginOverlap 생성
  3. FActorEndOverlapSignature(제공 시그니처)와 동일한 함수 시그니처를 갖는 ActorEndOverlap 생성

 

2. ActorBeginOverlap.cpp

#include "C01_ActorBeginOverlap.h"
#include "Global.h"
#include "Components/BoxComponent.h"
#include "Components/SceneComponent.h"
#include "Components/TextRenderComponent.h"


AC01_ActorBeginOverlap::AC01_ActorBeginOverlap()
{
	CHelpers::CreateComponent<USceneComponent>(this, &Scene, "Scene");
	CHelpers::CreateComponent<UBoxComponent>(this, &Box, "Box", Scene);
	CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Text", Scene);


	Box->SetRelativeScale3D(FVector(3));
	Box->bHiddenInGame = false;

	Text->SetRelativeLocation(FVector(0, 0, 100));
	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeScale3D(FVector(2));
	Text->TextRenderColor = FColor::Red;
	Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;
	Text->Text = FText::FromString(GetName());

}

void AC01_ActorBeginOverlap::BeginPlay()
{
	Super::BeginPlay();
	
   	 // OnActorBeginOverlap 대리자 함수는 함수 포인터를 활용해 ActorBeginOverlap을 호출
	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);
}

 

커스텀 대리자 함수 활용 방법

1. Trigger.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C03_Trigger.generated.h"

DECLARE_DELEGATE(FBoxLightBeginOverlap); //void  __(void)
DECLARE_DELEGATE(FBoxLightEndOverlap); //void  __(void)
DECLARE_DELEGATE_RetVal_OneParam(FString, FBoxLightRandomBeginOverlap, FLinearColor);

UCLASS()
class U03_CPP_API AC03_Trigger : public AActor
{
	GENERATED_BODY()
	
private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Scene;

	UPROPERTY(VisibleDefaultsOnly)
		class UBoxComponent* Box;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	

	AC03_Trigger();

protected:

	virtual void BeginPlay() override;

private:
	UFUNCTION()
		void ActorBeginOverlap(AActor* OverlappedActor, AActor* OtherActor);

	UFUNCTION()
		void ActorEndOverlap(AActor* OverlappedActor, AActor* OtherActor);

public:
	FBoxLightBeginOverlap OnBoxLightBeginOverlap;
	FBoxLightEndOverlap OnBoxLightEndOverlap;
};
  1. DECLARE_DELEGATE 활용하여 커스텀 대리자 함수 시그니처를 생성합니다.
  2. 커스텀 대리자 함수 시그니처를 통해 커스텀 대리자 함수를 선언합니다(eg. OnBoxLightBeginOverlap)

 

2. Trigger.cpp

#include "03_Collision/C03_Trigger.h"
#include "Global.h"
#include "Components/BoxComponent.h"
#include "Components/TextRenderComponent.h"

AC03_Trigger::AC03_Trigger()
{
	CHelpers::CreateComponent<USceneComponent>(this, &Scene, "Scene");
	CHelpers::CreateComponent<UBoxComponent>(this, &Box, "Box", Scene);
	CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Text", Scene);


	Box->SetRelativeScale3D(FVector(3));
	Box->bHiddenInGame = false;

	Text->SetRelativeLocation(FVector(0, 0, 100));
	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeScale3D(FVector(2));
	Text->TextRenderColor = FColor::Red;
	Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;
	Text->Text = FText::FromString(GetName());
}

void AC03_Trigger::BeginPlay()
{
	Super::BeginPlay();
	
	OnActorBeginOverlap.AddDynamic(this, &AC03_Trigger::ActorBeginOverlap);
	OnActorEndOverlap.AddDynamic(this, &AC03_Trigger::ActorEndOverlap);

}

void AC03_Trigger::ActorBeginOverlap(AActor * OverlappedActor, AActor * OtherActor)
{
	// IsBound : 커스텀 대리자 함수의 바인딩이 수행되었는지 체크
	if (OnBoxLightBeginOverlap.IsBound())
    		// Exectue : 커스텀 대리자 함수 실행
		OnBoxLightBeginOverlap.Execute();
}

// FBoxLightEndOverlap 대리자 함수 시그니처와 동일한 사용자 정의 함수 
void AC03_Trigger::ActorEndOverlap(AActor * OverlappedActor, AActor * OtherActor)
{
	// IsBound : 커스텀 대리자 함수의 바인딩이 수행되었는지 체크
	if (OnBoxLightEndOverlap.IsBound())
    		// Exectue : 커스텀 대리자 함수 실행
		OnBoxLightEndOverlap.Execute();
}
  1. IsBound() : 커스텀 대리자 함수의 "Binding"여부를 체크
  2. Execute() : 대리자 함수의 실행

 

3. Light.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C04_Light.generated.h"

UCLASS()
class U03_CPP_API AC04_Light : public AActor
{
	GENERATED_BODY()

private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Scene;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

	UPROPERTY(VisibleDefaultsOnly)
		class UPointLightComponent* Light;

	UPROPERTY(VisibleDefaultsOnly)
		class UPointLightComponent* Light2;

public:	
	AC04_Light();

protected:
	virtual void BeginPlay() override;

private:
	UFUNCTION()
		void OnLight();

	UFUNCTION()
		void OffLight();

};

 

4. Light.cpp

#include "C04_Light.h"
#include "Global.h"
#include "C03_Trigger.h"
#include "Components/TextRenderComponent.h"
#include "Components/PointLightComponent.h"

AC04_Light::AC04_Light()
{
	CHelpers::CreateComponent<USceneComponent>(this, &Scene, "Scene");
	CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Text", Scene);
	CHelpers::CreateComponent<UPointLightComponent>(this, &Light, "Light", Scene);
	CHelpers::CreateComponent<UPointLightComponent>(this, &Light2, "Light2", Scene);

	Text->SetRelativeLocation(FVector(0, 0, 100));
	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeScale3D(FVector(2));
	Text->TextRenderColor = FColor::Red;
	Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;
	Text->Text = FText::FromString(GetName());

	//1e+4f = 10^4 = 10000;
	//1e-6f = 10^-6 = 0.000001;
	Light->Intensity = 1e+4f;
	Light->AttenuationRadius = 200;
	Light->LightColor = FColor(255, 128, 50);

	Light2->SetRelativeLocation(FVector(200, 0, 0));
	Light2->Intensity = 1e+4f;
	Light2->AttenuationRadius = 200;
	Light2->LightColor = FColor(255, 128, 50);
}

void AC04_Light::BeginPlay()
{
	Super::BeginPlay();
	
	Light->SetVisibility(false);
	Light2->SetVisibility(false);

	TArray<AActor*> actors;
	UGameplayStatics::GetAllActorsOfClass(GetWorld(), AC03_Trigger::StaticClass(), actors);
	CheckFalse(actors.Num() > 0);

	AC03_Trigger* trigger = Cast<AC03_Trigger>(actors[0]);
    
    	// BindUFunction: Trigger 클래스의 커스텀 대리자 함수와 "바인딩"을 수행합니다!
	trigger->OnBoxLightBeginOverlap.BindUFunction(this, "OnLight");
	trigger->OnBoxLightEndOverlap.BindUFunction(this, "OffLight");
}

// FBoxLightBeginOverlap 대리자 함수 시그니처와 동일한 사용자 정의 함수 
void AC04_Light::OnLight()
{
	Light->SetVisibility(true);
	Light2->SetVisibility(true);
}

// FBoxLightEndOverlap 대리자 함수 시그니처와 동일한 사용자 정의 함수 
void AC04_Light::OffLight()
{
	Light->SetVisibility(false);
	Light2->SetVisibility(false);
}
  • BindFunction() : 대리자 함수에서 호출할 함수 포인터를 연결합니다!

 

Multicast

1. 기본구조

DECLARE_MULTICAST_DELEGATE_TwoParams(MULTICAST_DELEGATE_NAME, PARAM_1_TYPE, PARAM_2_TYPE);
  • 기본 구조는 위와 동일합니다.
  • 다만, "DECLARE_MULTICAST_DELEGATE"를 통해 반환 값이 없는 대리자 함수 시그니처를 생성합니다.
  • 더불어, 대리자 함수의 실행을 "Execute"가 아니라, "Broadcast"를 통해 수행합니다.

 

Event

1. 기본 구조

  • 위에서 살펴본 Delegate와 기본 구조는 동일합니다.
  • 다만, "IsBound" + "Execute" 등의 대리자 함수의 실행은 대리자 함수가 선언된 클래스 내부에서만 가능합니다!
  • 따라서, "DECLARE_DELEGATE" 대리자 함수 시그니처 선언 또한 클래스 내부에 선언합니다.

 

 

 

 

 

'게임개발 > Unreal C++' 카테고리의 다른 글

[Unreal]#23_FString, FText, FName 변환  (0) 2023.02.05
[Unreal]#22_TTuple  (0) 2023.02.05
[Unreal]#20_Log  (0) 2022.11.02
[Unreal]#19_Custom Behavior Tree Service  (0) 2022.10.05
[Unreal]#18_Custom Behavior Tree Task  (0) 2022.10.05
  1.  
  2. [Unreal]#21_Custom Delegate 
'게임개발/Unreal C++' 카테고리의 다른 글
  • [Unreal]#23_FString, FText, FName 변환
  • [Unreal]#22_TTuple
  • [Unreal]#20_Log
  • [Unreal]#19_Custom Behavior Tree Service
Hardii2
Hardii2
Hardii2
개발 블로그
Hardii2
전체
오늘
어제
  • 분류 전체보기
    • 알고리즘
    • 웹 개발
      • Node.js
      • React
    • 게임개발
      • DirectX12
      • 관련 지식
      • Unreal C++
      • Unreal 블루프린트
    • 언어
      • Effective C++
      • Basic C++
      • 디자인 패턴
      • 자료구조
      • 기술 질문
    • 문제 풀이
      • BOJ 문제 풀이
      • Programmers 문제 풀이
      • geeksForgeeks 문제 풀이
    • 수학
      • 확률과 통계
      • 게임수학
    • 개인프로젝트
    • 그룹프로젝트
      • PM
      • Dev
    • Github

블로그 메뉴

  • 홈
  • 글쓰기

공지사항

인기 글

태그

  • Effective C++
  • 디자인 패턴
  • BFS
  • 알고리즘
  • unreal
  • 정렬
  • 개발
  • C++
  • Unreal Blueprint
  • 최단 경로
  • 트리
  • stl
  • 기술 질문
  • set
  • 우선순위 큐
  • dfs
  • DP
  • BOJ
  • 그래프
  • programmers

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
Hardii2
[Unreal]#21_Custom Delegate
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.