[UE/Basic] 델리게이트

2025. 1. 7. 21:01·Unrael/Basic

1. 개요

델리게이트가 무엇이며 어떻게 내부적으로 작동하는지 살펴보자

 

2. 델리게이트

1. 델리게이트란?

어떤 이벤트가 발생하였을 때 등록된 객체들에게 "이벤트 발생했어요!"라고 알리는 기능(브로드캐스트)을 말한다.

SubObject는 이벤트를 감지하는 오브젝트이다.

옵저버 리스트를 보유하고 있으며 이벤트 발생시 리스트를 순회하며 콜백함수를 호출해준다.

 

Observer는 이벤트가 발생되었을 때 콜백 함수가 호출되길 원하는 오브젝트이다.

콜백 함수를 보유하고 있으며 SubObject에 의해 콜백함수를 호출받는다.

 

게임이 시작되었을 때

Observer는 SubObject에게 델리게이트를 등록하고 이벤트가 발생하면 호출받을 수 있다.

 

이는 디자인 패턴 중 '관찰자 패턴(Observer Pattern)'과 동일하다.

트위터에서 특정 대상을 팔로우(Follow)하면 대상이 글을 작성할 때마다 팔로워들에게 게시글 알림이 전송된다.

 

2. 델리게이트 장점

Subobject 오브젝트는 Observer가 어떤 오브젝트인지 알지 못해도 콜백함수를 호출해 줄 수 있다.

Subobect에서 필요로 하는 콜백함수를 정의한다. (매개변수, 반환타입)

Observer는 Subject가 정의한 콜백함수에 맞게 함수를 정의하여 등록하면 이벤트 발생시 함수를 호출받을 수 있다.

 

객체들간의 의존도가 낮으며 향후 코드 변경이 수월해 진다는 장점이 있다.

 

3. 델리게이트 활용 단계

델리게이트를 활용하는 방법은 다음과 같다.

  1. 관찰 대상자 (Suboject)
    • 델리게이트 정의하기
    • 델리게이트 변수 선언하기
    • 델리게이트 브로드캐스트하기
  2. 옵저버 (Observer)
    • 콜백함수 선언 및 정의하기
    • 델리게이트에 콜백함수 바인드하기

 

1. 델리게이트 정의하기

델리게이트 정의는 아래와 같은 형태를 유지한다.

DECLARE_{연결 관계}_{바인드 범위}_DELEGATE_{반환타입 유무}_{매개변수 유무} ()

 

연결 관계

연결 관계는 관찰 대상자와 옵저버가 어떤 연결 관계를 가지는지 말한다.

// 1:1 관계일 경우
DECLARE_DELEGATE() /* 기본값으로 변경된 것이 없다. */

// 1:N 관계일 경우
DECLARE_MULTICAST_DELEGATE()

 

바인드 범위

콜백 함수의 바인드 범위를 블루프린트까지 허용할 것인지를 말한다.

// C++ Only 바인드 가능
DECLARE_DELEGATE() /* 기본값으로 변경된 것이 없다. */

// C++ or Blueprint 바인드 가능
DECLARE_DYNAMIC_DELEGATE()

 

반환타입 유무

콜백함수에 반환타입 있을 경우 "RetVal"을 붙여준다.

// 콜백 함수의 반환타입이 있는 경우
DECLARE_DELEGATE_RetVal()

// 콜백 함수의 반환타입이 없는 경우
DECLARE_DELEGATE() /* 기본값으로 변경된 것이 없다. */

// 예외) MULTICAST는 반환타입을 지정할 수 없다.
DECLARE_MULTICAST_DELEGATE_RetVal() X

 

매개변수 유무

매개변수의 개수에 따라 "_Param"을 붙여준다.

// 콜백함수의 매개변수가 없다.
DECLARE_DELEGATE()

// 콜백함수의 매개변수가 하나 있다.
DECLARE_DELEGATE_OneParam()

// 콜백함수의 매개변수가 두 개 있다.
DECLARE_DELEGATE_TwoParams()

 

 

그렇다면 예시를 통해 정리해보자.

// C++ Only & 1:1 관계 & 반환 타입 X & 매개 변수 X
DECLARE_DELEGATE(FSignature);

// C++ Only & 1:N 관계 (MULTICAST) & 반환 타입 X & 매개 변수 X
DECLARE_MULTICAST_DELEGATE(FSignature2);

// C++ or Blueprint (DYNAMIC) & 1:1 관계 & 반환 타입 O (RetVal) & 매개 변수 X
DECLARE_DYNAMIC_DELEGATE_RetVal(float, FSignature3);

// C++ or Blueprint (DYNAMIC) & 1:N 관계 (MULTICAST) & 반환 타입 X & 매개 변수 X
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FSignature4);

// C++ or Blueprint (DYNAMIC) & 1:N 관계 (MULTICAST) & 반환 타입 X & 매개 변수 1 (OneParam)
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSignature5, float, NewValue);

 

 

2. 델리게이트 변수 선언하기

관찰 대상자의 델리게이트는 변수 선언은 아래 코드와 같다.

// 델리게이트 매크로 정의
DECLARE_MULTICAST_DELEGATE_OneParam(FOnAttributeChangedSignature, float);

// 델리게이트 변수 선언 1
FOnAttributeChangedSignature OnHealthChanged;

// 델리게이트 변수 선언 2 (블루프린트에서 바인드 가능)
UPROPERTY(BlueprintAssignable)
FOnAttributeChangedSignature OnHealthChanged2;

 

 

3. 델리게이트 브로드캐스트하기

브로드캐스트는 옵저버 객체들의 콜백함수를 순회하며 호출하는 작업을 말한다.

즉, 이벤트가 발생하였을 때 옵저버들에게 알리는 기능이다.

OnHealthChanged.Broadcast(AuraAttributeSet->Get_health());

 

 

옵저버

1. 콜백함수 등록하기

옵저버 클래스에서 델리게이트 정의에 맞게 함수를 선언한다.

// DECLARE_DYNAMIC_MULTICAST_OneParam(FSignatured, float);
void HandledCurrentChanged(float InChangedHP);

 

 

2. 델리게이트에 콜백함수 바인드하기

델리게이트 바인드 함수는 다양하게 제공된다.

순간적으로 머리가 띵해진다. (저게 뭐지..)

하나씩 차근차근 살펴보자

 

위 리스트는 호출 가능한 바인드 함수들이다.

바인드 함수는 크게 2가지로 분류할 수 있다.

  • Bind-
  • Add-

 

Bind는 1:1 관계를 가진 델리게이트의 바인드 함수들이다.

Add는 1:N 관계를 가진 델리게이트의 바인드 함수들이다.

// 1:1 관계
DECLARE_DELEGATE(FSignature);
FSignature OneByOneSignature;

// 1:1 관계에서는 Bind함수가 호출 가능하다.
OneByOneSignature.Bind~();
// 1:N 관계
DECLARE_MULTICAST_DELEGATE(FSignature);
FSignature OneByManySignature;

// 1:N 관계에서는 Add함수가 호출 가능하다.
OneByManySignature.Add~();

 

 

그 다음으로 접미사(Raw, SP, Static, Lambda)는 아래과 같다.

  • Raw - 콜백함수로 원시 포인터의 멤버 함수를 지정한다.
  • SP - 콜백함수로 스마트 포인터의 멤버 함수를 지정한다.
  • Static - 콜백함수로 정적 함수를 지정한다.
  • Lambda - 콜백함수로 임시 함수를 지정한다.
  • Dynamic - 콜백함수로 UObject 기반의 멤버 함수를 지정한다.

즉, 정의한 콜백 함수의 생김새에 따라 바인드 함수가 정해진다고 생각하면 편하다.

 

예시를 살펴보자

/* 1:1 관계 */
// Raw 포인터를 사용하여 멤버 함수를 바인딩
MyDelegate.BindRaw(this, &MyClass::MyFunction);

// 스마트 포인터를 사용하여 멤버 함수를 바인딩
MyDelegate.BindSP(MySharedPointer, &MyClass::MyFunction);

// 전역 함수 또는 정적 멤버 함수를 바인딩	
MyDelegate.BindStatic(&GlobalFunction);

// 람다 함수를 바인딩
MyDelegate.BindLambda([]() { UE_LOG(LogTemp, Warning, TEXT("Lambda called!")); });
/* 1:N 관계 */
// Raw 포인터를 사용하여 멤버 함수를 추가.
MyMulticastDelegate.AddRaw(this, &MyClass::MyFunction);

// 스마트 포인터를 사용하여 멤버 함수를 추가
MyMulticastDelegate.AddSP(MySharedPointer, &MyClass::MyFunction);

// 전역 함수 또는 정적 멤버 함수를 추가
MyMulticastDelegate.AddStatic(&GlobalFunction);

// 람다 함수를 추가
MyMulticastDelegate.AddLambda([]() { UE_LOG(LogTemp, Warning, TEXT("Lambda called!")); });

// UObject 기반 멤버 함수를 런타임 추가(필수: UFUNCTION)
MyDynamicMulticastDelegate.AddDynamic(this, &UMyClass::MyFunction);

 

 

4. 정리

델리게이트는 게임 개발시 다양하게 활용된다.

  • 피격시 HP 변경 후 UI에 반영할 때
  • AI가 플레이어 감지 후 다른 AI에게 알릴 때
  • 스킬 사용 후 MP 변경 후 UI에 반영할 때

많이 사용되는 만큼 잘 익혀서 게임 개발에 녹여낼 수 있도록 하자.

 

참고
 

Observer Design Pattern | Code Pumpkin

Observer Design Pattern is useful when you are interested in the state of an object and want to get notified whenever there is any change.

codepumpkin.com

 

'Unrael > Basic' 카테고리의 다른 글

[UE/Basic] 자료구조 - TArray  (0) 2025.01.22
[UE/Basic] 액터의 라이프 사이클  (1) 2025.01.21
[UE/Basic] 액터 (Actor)  (0) 2024.12.20
[UE/Basic] 캐릭터 클래스 (Character)  (0) 2024.12.20
[UE/Basic] 액터의 이동  (0) 2024.12.11
'Unrael/Basic' 카테고리의 다른 글
  • [UE/Basic] 자료구조 - TArray
  • [UE/Basic] 액터의 라이프 사이클
  • [UE/Basic] 액터 (Actor)
  • [UE/Basic] 캐릭터 클래스 (Character)
DevColIn
DevColIn
복잡함을 단순하게
  • DevColIn
    심플한 코딩생활
    복잡함을 단순하게
  • 전체
    오늘
    어제
    • 전체보기 (223)
      • Unreal 부트캠프 (49)
        • TIL (34)
        • 사전캠프 (7)
        • 본캠프 (8)
      • Unrael (10)
        • 환경설정 (0)
        • Basic (19)
        • Component (5)
        • GAS (GameplayAbilitySystem) (3)
        • AI (2)
        • Implement (10)
        • UI (1)
        • Error (1)
        • Network (2)
        • Tip (1)
      • Level Design (5)
      • Math (1)
      • Design Pattern (16)
      • Computer Science (2)
        • Network (1)
        • Database (1)
      • Algorithm (79)
        • Basic (4)
        • Practice (74)
      • C++ (4)
        • Basic (4)
      • Tool (0)
      • Game (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    하드 레퍼런싱
    KPT회고
    unreal
    basic
    알고리즘
    AI
    게임동기화
    unrealengine
    Algorithm
    assetmanager
    사전캠프
    Design Pattern
    component
    본캠프
    액터
    레벨디자인
    Implement
    Animation
    소프트 레퍼런신
    DesignPattern
    디자인패턴
    Til
    c++
    내일배움캠프
    gas
    디자인 패턴
    actor
    GameplayEffect
    퀘스트
    tsoftobjectptr
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
DevColIn
[UE/Basic] 델리게이트
상단으로

티스토리툴바