본문 바로가기
Unreal/Manual

Unreal C++ 언리얼 Delegate 델리게이트

by Dev_카페인 2023. 11. 2.
반응형

[Unreal/C++] 언리얼 Delegate 델리게이트

 

Delegate (델리게이트)로 C++ 오브젝트 상의 멤버 함수 호출을 안전한 방식으로 할 수 있다.

델리게이트를 사용하여 임의 오브젝트의 멤버 함수에 동적으로 바인딩시킬 수 있으며, 그 오브젝트에서 함수를 호출할 수 있습니다.

 

델리게이트 오브젝트는 복사해도 안전하다.

델리게이트는 값으로 전달 가능하지만 heap 에 메모리를 할당해야 하기 때문에 추천하지 않는다.

가급적 델리게이트는 참조 전달해야 한다.

델리게이트는 싱글-캐스트와 멀티-캐스트 모두 지원된다.

다이나믹 델리게이트도 안전하게 Serialize 시킬 수 있다.

 

델리게이트 선언

델리게이트의 선언은 제공되어 있는 선언 매크로 중 하나를 사용한다.

사용되는 매크로는 델리게이트에 바인딩되는 함수의 시그너처에 따라 결정된다.

언리얼에서는 델리게이트용 범용 함수 시그너처의 다양한 선언 조합을 미리 정의해놓았다.

필요에 따라 반환값과 파라미터에 대한 유형 이름을 변경하여 사용한다.

아래와 같은 내용이 지원된다.

  • 값을 반환하는 함수
  • "페이로드"(payload, 유상) 변수 4 개 까지
  • 함수 파라미터 8 개 까지
  • 'const' 로 선언된 함수

델리게이트

 

멀티-캐스트, 다이내믹 델리게이트에 대한 매크로도 제공된다.

  • DECLARE_MULTICAST_DELEGATE...
  • DECLARE_DYNAMIC_DELEGATE...
  • DECLARE_DYNAMIC_MULTICAST_DELEGATE...
  • DECLARE_DYNAMIC_DELEGATE...
  • DECLARE_DYNAMIC_MULTICAST_DELEGATE...

 

델리게이트 시그너처 선언은 함수 본문은 제외한 글로벌 영역, 네임스페이스 안, 클래스 선언부 안에서도 가능하다.

 

 

델리게이트 바인딩

UObject 또는 공유 포인터 클래스의 멤버에 바인딩하는 경우 대리자 시스템은 개체에 대한 약한 참조를 유지할 수 있으므로, 개체가 소멸되는 경우 IsBound()또는 ExecuteIfBound()를 활용할 수 있다.

이러한 함수의 변형, 인수 및 구현 내용은 아래 경로에 정의되어 있다.

\UE4\Engine\Source\Runtime\Core\Public\Templates\ DelegateSignatureImpl.inl

델리게이트 함수

 

 

페이로드 데이터

대리자에 바인딩할 때 페이로드 데이터를 전달할 수 있다.

페이로드 데이터는 바인딩된 함수에 직접 전달되는 임의의 변수이다.

대리자 자체 내에 매개변수를 저장할 수 있으므로 매우 유용하다.

동적을 제외한 모든 대리자 유형은 페이로드 변수를 자동으로 지원한다.

 

 

델리게이트 실행

델리게이트 실행

멀티 캐스트 델리게이트의 경우 Broadcast()를 사용한다.

 

 

다이나믹 델리게이트 선언

다이나믹 델리게이트

 

다이나믹 델리게이트 바인딩

델리게이트 바인딩

다이나믹 델리게이트는 직렬화(Serialize)화가 가능하고 UPROPERTY 메크로를 통해서 블루프린트에서 델리게이트 바인드가 가능합니다.

멀티캐스트 델리게이트 바인딩

델리게이트 바인딩

 

멀티캐스트 실행

 

 

싱글캐스트와 차이점은 Unbind가 Clear로 되고 Execute가 Broadcast로 바뀌었다.

 

 

 

// SingleCast
DECLARE_DELEGATE(FDele_Single);
DECLARE_DELEGATE_OneParam(FDele_Single_OneParam, int32);

// MultiCast
DECLARE_MULTICAST_DELEGATE(FDele_Multi);
DECLARE_MULTICAST_DELEGATE_OneParam(FDele_Multi_OneParam, int32);

//Dynamic
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDele_Dynamic);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDele_Dynamic_OneParam, int32, SomeParameter);


...........

public :
	FDele_Single Fuc_DeleSingle;
	FDele_Single_OneParam Fuc_DeleSingle_OneParam;

	FDele_Multi Fuc_DeleMulti;
	FDele_Multi_OneParam Fuc_DeleMulti_OneParam;

	UPROPERTY(BlueprintAssignable, VisibleAnywhere, BlueprintCallable, Category = "Event")
		FDele_Dynamic Fuc_Dynamic;

	UPROPERTY(BlueprintAssignable, VisibleAnywhere, BlueprintCallable, Category = "Event")
		FDele_Dynamic_OneParam Fuc_Dynamic_OneParam;

 

 

		Fuc_DeleSingle.BindUFunction(this, FName("CallDeleFunc_Single"));
		Fuc_DeleSingle_OneParam.BindUFunction(this, FName("CallDeleFunc_Single_OneParam"));

		Fuc_DeleMulti.AddUFunction(this, FName("CallDeleFunc_Multi_1"));
		Fuc_DeleMulti.AddUFunction(this, FName("CallDeleFunc_Multi_2"));

		Fuc_DeleMulti_OneParam.AddUFunction(this, FName("CallDeleFunc_Multi_OneParam_1"));
		Fuc_DeleMulti_OneParam.AddUFunction(this, FName("CallDeleFunc_Multi_OneParam_2"));
		
		Fuc_Dynamic.AddDynamic(this, &ClassName::CallDeleFunc_Dynamic);
		Fuc_Dynamic_OneParam.AddDynamic(this, &ClassName::CallDeleFunc_Dynamic_OneParam);

// Delegate호출하는 부분
		if(Fuc_DeleSingle.IsBound())	Fuc_DeleSingle.Execute();
		if(Fuc_DeleSingle_OneParam.IsBound()) Fuc_DeleSingle_OneParam.Execute(123);
		if(Fuc_DeleMulti.IsBound()) Fuc_DeleMulti.Broadcast();
		if(Fuc_DeleMulti_OneParam.IsBound()) Fuc_DeleMulti_OneParam.Broadcast(456);
		if (Fuc_Dynamic.IsBound()) Fuc_Dynamic.Broadcast();
		if (Fuc_Dynamic_OneParam.IsBound()) Fuc_Dynamic_OneParam.Broadcast(999);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형