【UE4】C++의 (Singlecast) Dynamic Delegate에 Blueprint에서 바인딩

오랜만의 업데이트.

Blueprint의 이벤트 디스패처는 Unreal C++에서 말하는 Dynamic Multicast 대리자인 것 같다.
하지만 언리얼 C++ 에서 제공하는 블루프린트용 유틸리티에는 멀티캐스트는 너무 과장된 국면이 비교적 많다.
이번에는 Multicast가 아닌 델리게이트를 Blueprint에서 바인딩하는 방법을 발견했으므로 메모를 남겨 둡니다.
  • 대리인 - UE4 공식

  • 자신을 위한 복습: Unreal C++ 델리게이트에 Blueprint 이벤트 바인딩



    Unreal C++ 에서 제공한 대리자를 Blueprint 로 바인드할 수 있도록 하려면 DECLARE_DYNAMIC_MULTICAST_DELEGATE 매크로에서 대리자형을 선언하고 UPROPERTY(BlueprintAssignable) 를 지정한 대리자 변수를 준비해 준다.
    다음은 Actor Component 로부터 파생한 Dynamic Delegate Component 로, 델리게이트의 동작 확인을 하는 예.

    (예) DynamicDelegateComponent.h
    #include "CoreMinimal.h"
    #include "Components/ActorComponent.h"
    #include "DynamicDelegateComponent.generated.h"
    
    DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBlueprintAssignableSignature);
    
    UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
    class STATEMACHINE01_API UDynamicDelegateComponent : public UActorComponent
    {
        GENERATED_BODY()
    public: 
        // Sets default values for this component's properties
        UDynamicDelegateComponent();
    protected:
        // Called when the game starts
        virtual void BeginPlay() override;
    public: 
        // Called every frame
        virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
    
    public: // [RINDERON] properties exposed to blueprint
        UPROPERTY(BlueprintAssignable, Category = "Dynamic Delegate Component")
            FBlueprintAssignableSignature OnEventDispatcherCalled;
    };
    

    (예) DynamicDelegateComponent.cpp (일부)
    // Called every frame
    void UDynamicDelegateComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
    {
        Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
    
        // [RINDERON]
        OnEventDispatcherCalled.Broadcast();
    }
    

    그런 다음 Blueprint 측에서 액터에 Dynamic Delegate Component를 추가하고,



    예를 들면 Event BeginPlay 로 다음과 같이 짜는다.



    이것을 실행하면(자), UDynamicDelegateComponent::TickComponent() 내의 델리게이트의 Broadcast()가 움직여, 매 프레임 Print String 가 불려 갑니다.



    Singlecast로 충분하다면


  • 원래 이벤트는 1개 밖에 바인드할 생각이 없는 경우
  • 오히려 1개, 혹은 0개의 이벤트 밖에 바인드 할 수 있게 하고 싶은 경우



  • 이런 국면은 비교적 많았고, 이번에는 Unreal C++에서 준비한 Singlecast 델리게이트를 Blueprint로 바인딩할 수 없는지, 여러가지 시험해 보았다.
    솔직히, 할 수 있다고는 생각하지 않았지만, 되어 버렸다.

    (예) DynamicDelegateComponent.h (개)
    #include "CoreMinimal.h"
    #include "Components/ActorComponent.h"
    #include "DynamicDelegateComponent.generated.h"
    
    DECLARE_DYNAMIC_DELEGATE(FBlueprintCanBindThisSignature);
    
    UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
    class STATEMACHINE01_API UDynamicDelegateComponent : public UActorComponent
    {
        GENERATED_BODY()
    public: 
        // Sets default values for this component's properties
        UDynamicDelegateComponent();
    protected:
        // Called when the game starts
        virtual void BeginPlay() override;
    public: 
        // Called every frame
        virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
    
    public: // [RINDERON] properties exposed to blueprint
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dynamic Delegate Component")
            FBlueprintCanBindThisSignature OnDelegateCalled;
    };
    

    (예) DynamicDelegateComponent.cpp (개/일부)
    // Called every frame
    void UDynamicDelegateComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
    {
        Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
    
        // [RINDERON]
        OnDelegateCalled.ExecuteIfBound();
    }
    

    포인트는 2개:
  • Singlecast 대리자를 사용하고 싶기 때문에, DECLARE_DYNAMIC_MULTICAST_DELEGATE 는 아니고, DECLARE_DYNAMIC_DELEGATE 로 선언을 한다.
  • 대리자 변수를 UPROPERTY(BlueprintAssignable) 대신 UPROPERTY(BlueprintReadWrite)와 같이 일반적으로 Blueprint에 노출하는 속성처럼 처리합니다.

  • Blueprint에서 바인딩하는 방법은 다음과 같습니다.



    변수에 이벤트(함수)를 붙이는 그림이 기분 나쁜 것 같은 생각도 하는데, 원래 델리게이트란 그런 것이다.
    실행 결과는 의도대로 :



    주의


  • Dynamic 델리게이트이므로, 함수명으로 검색되고 나서 실행되므로, 일정한 부하가 걸린다.

  • Dynamic(동적) 대리자 - UE4 공식 참조.
  • 어느 쪽이든 Dynamic이므로, 함수를 1개 호출하는 것만으로는, Dynamic Multicast판과 동등 정도의 부하일 것이다. 부하 경감의 목적으로 사용해도 효과는 없다고 생각된다.
  • 장점은 델리게이트 변수를 Blueprint에 노출할 수 있어 뭔가 편리하게 사용할 수 있다는 것이며, 부하 경감이 아니다.

  • 이용은 자기책임으로 부탁합니다.
  • 대리자를 Blueprint에 공개적으로 공개하는 것 자체가 Blueprint 개념에서 벗어나는 것 같습니다. (발레하면 봉인 될지도?

  • 좋은 웹페이지 즐겨찾기