본문 바로가기
공부

[언리얼] 델리게이트 & 이벤트 특징 및 차이

by MY블로그 2024. 5. 9.

델리게이트(Delegate)

  • 델리게이트는 함수 포인터의 일종
  • 함수를 캡슐화하여 저장하고 호출 할 수 있게 한다.
  • 콜백 매커니즘을 사용
  • 델리게이트는 클래스 내부와 외부에서 모두 바인딩 할 수 있다.
  • 런타임중 호출 대상을 변경 할 수 있다.

1. A 클래스에서 매개변수(int32형)1개의 델리게이트를 선언

// A.h
#pragma once

#include "CoreMinimal.h"

class A : public UObject
{
    GENERATED_BODY()

public:
    DECLARE_DELEGATE_OneParam(FMyDelegate, int32); // 정수형 매개변수를 가지는 델리게이트 선언

    void DoSomething(int32 Value)
    {
        // A 클래스의 기능 구현
        UE_LOG(LogTemp, Log, TEXT("A::DoSomething called with value: %d"), Value);

        // 델리게이트 실행
        MyDelegate.Broadcast(Value);
    }

    FMyDelegate MyDelegate; // 델리게이트 멤버 변수
};

2. B 클래스에서 A 클래스의 델리게이트 바인딩

// B.h
#pragma once

#include "CoreMinimal.h"
#include "A.h" // A 클래스 헤더 포함

class B : public UObject
{
    GENERATED_BODY()

public:
    B()
    {
        // A 클래스의 델리게이트에 B 클래스의 함수 바인딩
        BindToADelegate(static_cast<A*>(GetTransientPackage()->GetDefaultSubobjectByName(TEXT("A"))));
    }

private:
    void BindToADelegate(A* AInstance)
    {
        // A 클래스의 델리게이트에 B 클래스의 함수 바인딩
        AInstance->MyDelegate.BindUObject(this, &B::OnADelegateInvoked);
    }

    void OnADelegateInvoked(int32 Value)
    {
        // A 클래스의 델리게이트가 호출될 때 실행되는 함수
        UE_LOG(LogTemp, Log, TEXT("B::OnADelegateInvoked called with value: %d"), Value);
    }
};

3. A클래스의 함수를 호출할때 델리게이트가 실행되며 B클래스의 바인딩 함수가 호출

// 사용 예시
A* AInstance = NewObject<A>();
AInstance->DoSomething(42); // A 클래스의 DoSomething 함수 호출
                           // A 클래스의 델리게이트가 실행되고, B 클래스의 OnADelegateInvoked 함수가 호출됨

이벤트(Event)

  • 멀티캐스트 델리게이트와 유사한 기능
  • 이벤트를 선언한 클래스내에서 Broadcast, IsBound, Clear 함수를 사용 할 수 있다.
  • 외부에서 직접 호출 할 수 없다.
  • 이벤트를 선언한 클래스에서만 호출 할 수 있다.
  • 안전하게 공개 인터페이스에 노출 할 수 있다.
  • 하나 이상의 델리게이트를 등록 할 수 있는 트리거 매커니즘을 사용

1. 이벤트 선언하기

// MyClass.h

#include "Delegates/Delegate.h"

class MyClass
{
public:
    // 이벤트 선언
    DECLARE_EVENT(MyClass, FMyEvent)
    FMyEvent& OnMyEvent() { return MyEvent; }

private:
    FMyEvent MyEvent;
};

2. 이벤트 리스너 추가하기

// MyOtherClass.h

class MyOtherClass
{
public:
    void OnEventTriggered();
};

// MyOtherClass.cpp

void MyOtherClass::OnEventTriggered()
{
    // 이벤트가 트리거될 때 실행될 코드
    UE_LOG(LogTemp, Warning, TEXT("Event Triggered!"));
}

3. 리스너를 이벤트에 바인딩

// MyClass의 인스턴스에서 MyOtherClass의 OnEventTriggered 함수를 이벤트에 바인딩할 수 있습니다.
// 이렇게 하면, MyClass에서 이벤트가 발생할 때마다 OnEventTriggered 함수가 호출됩니다.

MyClass MyClassInstance;
MyOtherClass MyOtherClassInstance;

// 이벤트 리스너로 MyOtherClassInstance의 OnEventTriggered 함수를 추가
MyClassInstance.OnMyEvent().AddRaw(&MyOtherClassInstance, &MyOtherClass::OnEventTriggered);

4. 이벤트 트리거

// MyClass 에서 이벤트 트리거
MyClassInstance.OnMyEvent().Broadcast();

// 이 코드를 실행하면, MyClassInstance의 MyEvent 이벤트가 트리거되며, 
// 이에 따라 MyOtherClassInstance의 OnEventTriggered 함수가 호출됩니다.

 

델리게이트이벤트의 차이점

델리게이트는 어느 클래스에서든 호출이 가능

이벤트는 이벤트를 선언한 클래스 내에서만 Broadcast, IsBound, Clear 함수를 사용

 

델리게이트 객체간의 통신을 위하여 사용

이벤트는 액터간 통신이나 컴포넌트간 통신에 사용

 

델리게이트 클래스 내부와 외부 모두에서 바인딩이 가능

이벤트는 선언한 클래스에서 제공하는 인터페이스를 통하여 외부에서 바인딩 가능

 

이벤트 docs 참고

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

 

댓글