본문 바로가기
[ Unreal5 ]/- 언리얼엔진5 실습

언리얼엔진5 Delegate

by MRG 2024. 6. 9.
728x90
반응형

▣ 델리게이트란?
- 델리게이트는 함수 포인터와 비슷한 개념으로, 특정 함수에 대한 참조를 저장하고 나중에 이를 호출할 수 있는 기능을 제공합니다.

- 사용: 특정 이벤트가 발생했을 때, 미리 지정된 함수나 메서드를 호출하는 데 사용됩니다.

 

▣ 왜 사용하는가?
- 이벤트 처리: 특정 조건이 발생했을 때 여러 개의 리스너 함수가 호출되어야 할 때 유용합니다.
- 콜백 메커니즘: 비동기 작업이 완료된 후 후속 작업을 수행해야 할 때 사용합니다.
- 코드의 결합도 감소: 코드의 모듈성을 높이고, 서로 다른 클래스나 모듈 간의 의존성을 줄일 수 있습니다.
- 유연한 설계: 런타임에 어떤 함수가 호출될지 유연하게 결정할 수 있습니다.

 

▣ Delegate (델리게이트)로 C++ 오브젝트 상의 멤버 함수 호출을 일반적이고 유형적으로 안전한 방식으로 할 수 있습니다. 델리게이트를 사용하여 임의 오브젝트의 멤버 함수에 동적으로 바인딩시킬 수 있으며, 그런 다음 그 오브젝트에서 함수를 호출할 수 있습니다. 호출하는 곳에서 오브젝트의 유형을 몰라도 말이지요.

▣ 델리게이트 오브젝트는 복사해도 완벽히 안전합니다. 델리게이트는 값으로 전달 가능하나 보통 추천할 만하지는 않은데, heap에 메모리를 할당해야 하기 때문입니다. 가급적이면 델리게이트는 항상 참조 전달해야 합니다.

▣ 델리게이트는 싱글-캐스트(형 변환)와 멀티-캐스트 모두 지원되며, 디스크에 안전하게 Serialize 시킬 수 있는 "다이내믹" 델리게이트도 물론입니다.

 

 

https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/

 

델리게이트

C++ 오브젝트 상의 멤버 함수를 가리키고 실행시키는 데이터 유형입니다.

docs.unrealengine.com

 

 

 

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/delegates-and-lamba-functions-in-unreal-engine?application_version=5.3

 

 

 

 

 

▣ 델리게이트 매크로 선언방법

DECLARE_DELEGATE(); //한 개 바인드 가능
DECLARE_MULTICAST_DELEGATE(); //여러 개 바인드 가능
DECLARE_DYNAMIC_DELEGATE(); //한 개 바인드 및 블루프린트도 바인드 가능
DECLARE_DYNAMIC_MULTICAST_DELEGATE(); //여러 개 바인드 및 블루프린트 바인드 가능
DECLARE_DELEGATE_RetVal(반환형, 델리게이트이름);
DECLARE_DELEGATE_RetVal_TwoParams(반환형, 델리게이트이름, 매개변수자료형 1, 매개변수자료형 2);
DECLARE_DELEGATE_TwoParams(델리게이트이름, 매개변수자료형 1, 매개변수자료형 2);

매개변수는 최대 9개까지 지원합니다.

 

 

 

▣ DelegateName은 앞에 F를 붙여서 선언합니다. 

 

▣ 델리게이트에 바인딩할 함수에는 항상 UFUNCTION 매크로를 사용해야 합니다.

 

▣ Unreal Engine에서 델리게이트를 사용하여 함수를 바인딩할 때 UFUNCTION 매크로를 사용하는 이유는 해당 함수가 리플렉션(reflection) 시스템에 의해 인식되고, 동적으로 바인딩될 수 있도록 하기 위함입니다. UFUNCTION 매크로가 없는 함수는 Unreal Engine의 리플렉션 시스템에 등록되지 않기 때문에, 동적 델리게이트(Dynamic Multicast Delegate)에 바인딩할 수 없습니다.

 

 

 

▣ 델리게이트바인딩이란?
델리게이트 바인딩이란 델리게이트가 어떤 함수를 호출해야 하는지 연결하는 것을 의미합니다. 즉, 델리게이트가 실행될 때 어떤 함수가 호출될지를 지정하는 것입니다. 바인딩을 통해 이벤트가 발생할 때 실행될 함수를 정의할 수 있습니다.

 

 

▣ 델리게이트 시스템은 특정 유형의 오브젝트를 이해하고 있으며, 이러한 오브젝트를 사용할 때는 추가적으로 사용할 수 있는 기능이 있습니다. UObject 나 공유 포인터 클래스 멤버에 델리게이트를 바인딩하는 경우, 델리게이트 시스템은 그 오브젝트에 대한 약한 레퍼런스를 유지할 수 있어, 델리게이트 치하에서 오브젝트가 소멸된 경우 IsBound() 나 ExecuteIfBound() 함수를 호출하여 처리해 줄 수 있습니다. 참고로 여러 가지 지원되는 오브젝트 유형에 대해서는 특수한 바인딩 문법이 사용됩니다.

 

▣ Bind() 기존 델리게이트 오브젝트에 바인딩합니다.


▣ BindStatic() raw C++ 포인터 글로벌 함수 델리게이트를 바인딩합니다.


▣ BindRaw() 날(raw) C++ 포인터 델리게이트에 바인딩합니다. 날 포인터는 어떠한 종류의 레퍼런스도 사용하지 않아, 만약 오브젝트가 델리게이트 치하에서 삭제된 경우 호출하기가 안전하지 않을 수도 있습니다. Execute() 호출 시에는 조심하세요!


▣ BindSP() 공유 포인터-기반 멤버 함수 델리게이트에 바인딩합니다. 공유 포인터 델리게이트는 오브젝트로의 약한 레퍼런스를 유지합니다. ExecuteIfBound()로 호출할 수 있습니다.


▣ BindUObject() UObject 기반 멤버 함수 델리게이트를 바인딩합니다. UObject 델리게이트는 오브젝트로의 약한 레퍼런스를 유지합니다. ExecuteIfBound()로 호출할 수 있습니다.


▣ UnBind() 이 델리게이트 바인딩을 해제합니다

 

 

 

▣ 다른 클래스에서 해당 클래스 헤더를 추가하고 Instance를 해서 Execute() 함수를 이용해서 바인딩한 함수를 호출하는 코드를 작성합니다.

 

▣ 단일캐스트 델리게이트 (DECLARE_DELEGATE, DECLARE_DELEGATE_OneParam 등):
하나의 함수만 바인딩할 수 있습니다. Execute()를 사용하여 호출합니다.

 

  델리게이트에 바인딩된 함수는 델리게이트의 Execute() 함수를 호출하여 실행됩니다. 델리게이트를 실행하기 전 "바인딩" 되었는지 반드시 확인해야 합니다. 이는 코드 안전성을 도모하기 위함인데, 초기화되지 않은 상태로 접근이 가능한 반환값과 출력 파라미터가 델리게이트에 있을 수 있기 때문입니다. 바인딩되지 않은 델리게이트를 실행시키면 일부 인스턴스에서 메모리에 낙서를 해버릴 수가 있습니다. 델리게이트가 실행해도 안전한 지는 IsBound()를 호출하여 검사해 볼 수 있습니다. 또한 반환값이 없는 델리게이트에 대해서는 ExecuteIfBound()를 호출할 수 있으나, 출력 파라미터는 초기화되지 않을 수 있다는 점 주의하시기 바랍니다.

 

 

 

 

 

 

 

 

멀티캐스트 델리게이트

여러 함수에 바인딩시켜 동시에 실행시킬수 있는 델리게이트 입니다.

docs.unrealengine.com

 

 

 

 

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/multicast-delegates-in-unreal-engine?application_version=5.3

 

 

▣ 멀티캐스트(multi-cast) 델리게이트는 싱글캐스트 델리게이트의 기능 대부분을 그대로 갖고 있습니다. 오브젝트로의 약 레퍼런스만 갖고 있으며, 구조체와 함께 사용 가능하고, 쉽게 복사할 수 있고, 등등입니다. 보통의 델리게이트와 마찬가지로 멀티캐스트 델리게이트 역시 로드/세이브 가능하며 원격으로 트리거 되나, 멀티캐스트 델리게이트 함수는 반환값을 사용할 수는 없습니다. 델리게이트 컬렉션을 쉽사리 옮기는 데 사용하기에 좋습니다.
특수한 유형의 멀티캐스트 델리게이트로, 제한적이나마 Broadcast(), IsBound(), Clear() 함수에 접근 가능합니다.

 

 

  Add() 이 멀티캐스트 델리게이트의 실행 목록에 함수 델리게이트를 추가합니다.
  AddStatic() raw C++ 포인터 글로벌 함수 델리게이트를 추가합니다.
  AddRaw() raw C++ 포인터 델리게이트를 추가합니다. raw 포인터는 어떠한 레퍼런스도 사용하지 않기에, 오브젝트가 자신의 델리게이트 하에서 삭제된 경우 호출 시 안전하지 않을 수 있습니다. Execute() 호출 시 주의하세요!
  AddSP() 공유 포인터 기반 (빠르지만 스레드 안전성은 떨어지는) 멤버 함수 델리게이트를 추가합니다. 공유 포인터 델리게이트는 자신의 오브젝트에 대한 약 레퍼런스를 유지합니다.
  AddUObject() UObject 기반 멤버 함수 델리게이트를 추가합니다. UObject 델리게이트는 자신의 오브젝트에 대한 약 레퍼런스를 유지합니다.
  Remove() 이 멀티캐스트 델리게이트의 실행 목록에서 함수를 제거합니다 (퍼포먼스는 O(N)입니다). 참고로 델리게이트 순서는 유지되지 않을 수 있습니다!
  RemoveAll() 지정된 UserObject에 바인딩된 이 멀티캐스트 델리게이트의 실행 목록에서 모든 함수를 제거합니다. 참고로 델리게이트 순서는 유지되지 않을 수 있습니다!

 

 

▣ 멀티캐스트 델리게이트를 통해 여러 함수 델리게이트를 붙인(attach) 다음, 멀티캐스트 델리게이트의 Broadcast() 함수를 호출하여 그 모두를 동시에 실행시킬 수 있습니다. 멀티캐스트 델리게이트 시그너처에는 반환값을 사용할 수 없습니다.

▣ 멀티캐스트 델리게이트에서의 Broadcast() 호출은 아무것도 바인딩되어 있지 않더라도 항상 안전합니다. 딱 한 가지 경우 조심해야 할 때가 있는데, 델리게이트를 사용하여 출력 변수를 초기화시킬 때로 보통은 매우 좋지 않은 일입니다.

▣ Broadcast() 호출 시 바인딩된 함수의 실행 순서는 정의되지 않습니다. 함수가 추가된 순서대로 실행되지 않을 수가 있습니다.

함수 설명
▣ Broadcast() 이 델리게이트를 만료되었을 수도 있는 것을 제외하고, 바인딩된 모든 오브젝트에 뿌립니다.

 

 

 

 

 

https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/Dynamic/

 

다이내믹 델리게이트

serialize 가능하면서 리플렉션도 지원하는 델리게이트입니다.

docs.unrealengine.com

 

▣ 다이내믹 델리게이트는 serialize 가능하며, 그 함수를 이름으로 찾을 수도 있으나, 일반 델리게이트보다는 느립니다.

 

▣ 언리얼에서 다이내믹 델리게이트는 함수이름을 기반으로 등록하고 호출하는 방식입니다.
이름 기반 저장 방식이라는 특징이 있지만 동작이 느리다는 단점이 있습니다. 

델리게이트 c++ 함수뿐만 아니라 블루프린트 함수도 연결 가능

 

 

728x90
반응형

댓글