Unreal Engine

Unreal Engine - 멀티캐스트 델리게이트

gbleem 2025. 4. 13. 19:17

0. 델리게이트


델리게이트 공식 문서

 

언리얼에서의 사용

  • 특정 상황이 발생했을 때 다른 객체에게 알려주기 위해서 사용환다.
  • 예를 들어,
    • 캐릭터의 체력이 0이 되었을 때 UI와 게임모드, 사운드 등에서 한 번에 반응을 할 때 사용할 수 있다.
    • 캐릭터가 체력과 관련된 델리게이트 변수를 가지고 있고, 이 변수를 체력이 0이 될때 BroadCast 하면
    • UI나 게임모드 등 다른 부분에서 바인딩 한 모든 함수들을 동시에 실행할 수 있다.
  • 예시
//character.h

DECLARE_MULTICAST_DELEGATE(FDeathDelegate);
...
public:
    void TakeDamage(float Damage);

    UPROPERTY()
    FDeathDelegate DeathDelegate;
    
//character.cpp
void AMyCharacter::TakeDamage(float Damage)
{
    Health -= Damage;
    
    if(Health <= 0)
    {
        Health = 0.f;
        DeathDelegate.Broadcast();
    }
}
//widget.cpp

void UMyWidget::BindCharacterDelegate(AMyCharacter* Character)
{
    if(Character)
    {
        Character->DeathDelegate.AddUObject(this, &UMyWidget::DeathUI);
    }
}

void UMyWidget::DeathUI()
{
    //Do something
}

 

델리게이트의 종류

  • single
    • DECLARE_DELEGATE
  • multicast
    • DECLARE_DYNAMIC_DELEGATE
    • 블루프린트에서 사용하기 위함!
  • dynamic single
    • DECLARE_MULTICAST_DELEGATE 
    • 여러 함수를 바인딩 가능
  • dynamic multicast
    • DECLARE_DYNAMIC_MULTICAST_DELEGATE

 

델리게이트 기본적인 사용 모습 코드 + 바인딩 함수 설명

  • 바인딩의 경우 DYNAMIC 델리게이트라면, AddDynamic()을 사용
  • 아닌 경우 AddRaw(), AddUObject(), AddLambda() 를 사용한다.
    • AddRaw : 일반 클래스(UObject 아닌) 를 바인딩 할 수 있지만, 가비지 컬렉션 불가능해서 메모리 관리가 필요
    • AddUObject : UObject 기반 클래스를 바인딩, 안전하다 (위젯, 액터, 컴포넌트 등)
    • AddLambda : 람다 함수를 바인딩, 아주 간단한 1회성 바인딩에 사용
//declare delegate
DECLARE_DELEGATE_TwoParams(FCustomDelegate, FString /*PlayerName*/, int32 /*PlayerScore*/);

UPROPERTY()
FCustomDelegate CustomDelegate;

//bind delegate
CustomDelegate.BindUObject(this, &ThisClass::LogPlayerInfo);

//using delegate
bool bBound = CustomDelegate.ExecuteIfBound(TEXT("Name"), 100);

 

 

1. 멀티캐스트 델리게이트 개념


멀티캐스트 델리게이트 공식 문서

 

여러 개의 함수를 한 번에 호출할 수 있도록 해주는 이벤트 브로드캐스트 시스템

언리얼에서는 UI 업데이트에서 많이 사용한다.

  • 싱글캐스트 델리게이트와 대부분의 기능이 동일하다.
  • 단, return 값을 사용할 수 없다.

 

2. 사용 방법 (멀티캐스트 델리게이트)


2 - 1. 델리게이트 타입 정의

  • 파라메터가 있는 경우는 OneParam 처럼 타입의 갯수를 넣어주고 변수 타입을 적어주면 된다.
  • 2개면 _TwoParams
DECLARE_MULTICAST_DELEGATE_OneParam(FOnCurrentHPChangedDelegate, float);
DECLARE_MULTICAST_DELEGATE(FOnOutOfCurrentHPDelegate);

 

2 - 1. 멤버 변수로 선언

FOnCurrentHPChangedDelegate OnCurrentHPChanged;
FOnOutOfCurrentHPDelegate OnOutOfCurrentHP;

 

2 - 3. 바인딩

  • 바인딩 함수

  • 바인딩 예시
void ADXPlayerCharacter::SetHPTextWidget(UUW_HPText* InHPTextWidget)
{
	UUW_HPText* HPWidget = Cast<UUW_HPText>(InHPTextWidget);
	if (IsValid(HPWidget))
	{
		HPWidget->InitializeHPTextWidget(StatusComponent);
		StatusComponent->OnCurrentHPChanged.AddUObject(HPWidget, &UUW_HPText::OnCurrentHPChange);
		StatusComponent->OnMaxHPChanged.AddUObject(HPWidget, &UUW_HPText::OnMaxHPChange);
	}
}
  • 바인딩 된 함수
    • 최초에 델리게이트 정의 시 사용한 타입을 매개변수로 넣어준다.
void UUW_HPText::OnMaxHPChange(float InMaxHP)
{
	MaxHPText->SetText(FText::FromString(FString::SanitizeFloat(InMaxHP)));
}

void UUW_HPText::OnCurrentHPChange(float InCurrentHP)
{
	CurrentHPText->SetText(FText::FromString(FString::SanitizeFloat(InCurrentHP)));
}

 

2 - 4. 브로드캐스트

  • Broadcast() 함수를 통해서, 바인딩된 모든 함수 델리게이트들을 실행한다.
  • 주의점
    • 아무것도 바인딩 되지 않은 상태에서 Broadcast() 함수를 호출해도 괜찮다.
    • 델리게이트를 사용해서 output 변수를 초기화하는 것은 하지 않는 것이 좋다.
    • 바인딩 된 순서와 다르게 실행될 수 있다.
void UDXStatusComponent::OnRep_CurrentHP()
{
	OnCurrentHPChanged.Broadcast(CurrentHP);
}

void UDXStatusComponent::OnRep_MaxHP()
{
	OnMaxHPChanged.Broadcast(MaxHP);
}