반응형
싱글 델리게이트 : 1-? 로 검색
멀티 델리게이트 : 2-? 로 검색
- 1번 델리게이트는 보스가 자기 자신에게만 쓰는 내부 호출
- 2번 델리게이트는 보스가 연결된 모든 미니언에게 동시에 신호를 주는 브로드캐스트 방식
📘 1번 순서: 싱글 델리게이트 – 보스 자기 자신 호출
단계설명
| 1-1 | DECLARE_DELEGATE_OneParam(FUseManaDele, float) |
| → 보스가 쓸 싱글 델리게이트 정의 | |
| 1-2 | FUseManaDele OnUseManaDelegate; |
| → 보스 클래스 내부에 변수 선언 | |
| 1-3 | OnUseManaDelegate.BindUObject(this, &ABoss::UseMana); |
| → 게임 시작 시, 자기 자신의 UseMana() 함수 바인딩 | |
| 1-4 | if (OnUseManaDelegate.IsBound()) |
| → 함수 연결 여부 확인 | |
| 1-5 | OnUseManaDelegate.Execute(10.0); |
| → 보스의 UseMana(10.0) 실행됨 |
✅ 핵심: 보스 내부에서 자기 함수 하나만 연결해 쓰는 싱글 델리게이트
📗 2번 순서: 멀티캐스트 델리게이트 – 여러 미니언에게 명령 전파
단계설명
| 2-1 | DECLARE_MULTICAST_DELEGATE_OneParam(FMinionSendBuffMultiDele, int32) |
| → 미니언에게 전파할 멀티캐스트 델리게이트 정의 | |
| 2-2 | FMinionSendBuffMultiDele OnMinionsSendBuffDelegate; |
| → 보스 클래스에 변수 선언 | |
| 2-3 | 미니언이 UGameplayStatics::GetActorOfClass()로 보스 찾음 |
| 2-4 | Boss->OnMinionsSendBuffDelegate.AddUObject(this, &AMinion::AddBuff); |
| → 미니언들이 보스의 델리게이트에 자기 함수 등록 | |
| 2-5 | if (OnMinionsSendBuffDelegate.IsBound()) |
| → 보스가 델리게이트에 함수가 바인딩되었는지 확인 | |
| 2-6 | OnMinionsSendBuffDelegate.Broadcast(Num); |
| → 등록된 미니언들의 AddBuff(Num) 전부 호출됨 |
✅ 핵심: 보스가 한 번 Broadcast(Num) 호출하면, 모든 구독한 미니언의 AddBuff() 실행됨
// Minion.cpp
#include "Minion.h"
#include "Boss.h"
#include "Kismet/GameplayStatics.h"
// Sets default values
AMinion::AMinion()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
void AMinion::AddBuff(int32 Value)
{
if (Index == Value)
{
UE_LOG(LogTemp, Warning, TEXT("Buff Actor : %s"), *GetActorLabel()); //GetActorNameOrLabel
}
}
void AMinion::DeadAll()
{
UE_LOG(LogTemp, Warning, TEXT("Time to Die : %s"), *GetActorLabel());
Destroy();
}
void AMinion::OtherFuncDead()
{
UE_LOG(LogTemp, Warning, TEXT("Time to Die2 : %s"), *GetActorLabel());
}
void AMinion::OtherBuff(int32 Value)
{
if (Index != Value)
{
UE_LOG(LogTemp, Warning, TEXT("OtherBuff Actor : %s"), *GetActorLabel());
}
}
// Called when the game starts or when spawned
void AMinion::BeginPlay()
{
Super::BeginPlay();
//월드에서 보스액터 찾기
AActor* FoundActor = UGameplayStatics::GetActorOfClass(GetWorld(), ABoss::StaticClass()); //2-3. 생성시 월드에서 보스액터 찾음
Boss = Cast<ABoss>(FoundActor);
//보스가 있으면 보스에게 바인딩
if (Boss != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Boss Connect"));
Boss->OnBossDeadDelegate.AddUObject(this, &AMinion::DeadAll);
Boss->OnMinionsSendBuffDelegate.AddUObject(this, &AMinion::AddBuff); //2-4. 찾은 보스액터를 캐스팅 한 후, OnMinionsSendBuffDelegate를 구독
Boss->OnOtherMinionsSendBuffDelegate.AddUObject(this, &AMinion::OtherBuff);
}
}
// Called every frame
void AMinion::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Boss.cpp
#include "Boss.h"
// Sets default values
ABoss::ABoss()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//보스 마나 초기값 부여
BossMana = 100.0;
}
// Called when the game starts or when spawned
void ABoss::BeginPlay()
{
Super::BeginPlay();
//델리게이트 자기자신에게 바인딩
OnUseManaDelegate.BindUObject(this, &ABoss::UseMana); //1-3. 바인딩
}
void ABoss::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
//보스가 소멸하면 델리게이트 제거
OnBossDeadDelegate.Clear();
OnMinionsSendBuffDelegate.Clear();
OnOtherMinionsSendBuffDelegate.Clear();
OnUseManaDelegate.Unbind();
}
void ABoss::CallDie()
{
//연결된 객체에서 이벤트(델리게이트) 전달
if (OnBossDeadDelegate.IsBound())
{
OnBossDeadDelegate.Broadcast();
}
//소멸
Destroy();
}
void ABoss::SendBuff(int32 Num)
{
if (OnUseManaDelegate.IsBound())//1-4. OnUseManaDelegate를 바인딩하고 있는게 있는지 체크
{
OnUseManaDelegate.Execute(10.0);//1-5. Execute로 이전에 지정한 &ABoss::UseMana 호출(끝)
}
if (OnMinionsSendBuffDelegate.IsBound())//2-5. OnMinionsSendBuffDelegate를 바인딩하고 있는게 있는지 체크
{
OnMinionsSendBuffDelegate.Broadcast(Num);//2-6. Broadcast로 구독하고있는 클래스의 지정된 함수를 호출(끝)
}
//마나가 0이되면 자폭
if (IsEmptyMana())
{
CallDie();
}
}
void ABoss::SendToOtherBuff(int32 Num)
{
if (OnUseManaDelegate.IsBound())
{
OnUseManaDelegate.Execute(20.0);
}
if (OnOtherMinionsSendBuffDelegate.IsBound())
{
OnOtherMinionsSendBuffDelegate.Broadcast(Num);
}
//마나가 0이되면 자폭
if (IsEmptyMana())
{
CallDie();
}
}
void ABoss::UseMana(float UsedManaValue)
{
if (BossMana <= 0)
{
BossMana = 0;
}
else
{
BossMana -= UsedManaValue;
}
UE_LOG(LogTemp, Warning, TEXT("Remained Mana : %f"), BossMana);
}
// Called every frame
void ABoss::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Minion.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Minion.generated.h"
class ABoss;
UCLASS()
class UNREALCPP5_API AMinion : public AActor
{
GENERATED_BODY()
protected:
ABoss* Boss;
private:
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"));
int32 Index;
public:
// Sets default values for this actor's properties
AMinion();
public:
UFUNCTION()
void AddBuff(int32 Value);
UFUNCTION()
void DeadAll();
UFUNCTION()
void OtherFuncDead();
UFUNCTION()
void OtherBuff(int32 Value);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
// Boss.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Boss.generated.h"
DECLARE_MULTICAST_DELEGATE(FBossDeadMultiDele) //
DECLARE_MULTICAST_DELEGATE_OneParam(FMinonSendBuffMultiDele, int32) //2-1. 멀티델리게이트 지정
DECLARE_MULTICAST_DELEGATE_OneParam(FOtherMinonSendBuffMultiDele, int32)
DECLARE_DELEGATE_OneParam(FUseManaDele, float) //1-1. 싱글델리게이트 지정
UCLASS()
class UNREALCPP5_API ABoss : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ABoss();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
private:
float BossMana;
public:
FBossDeadMultiDele OnBossDeadDelegate;
FMinonSendBuffMultiDele OnMinionsSendBuffDelegate; //2-2. 변수 지정
FOtherMinonSendBuffMultiDele OnOtherMinionsSendBuffDelegate;
FUseManaDele OnUseManaDelegate; //1-2. 변수 지정
public:
UFUNCTION(BlueprintCallable)
void CallDie();
UFUNCTION(BlueprintCallable)
void SendBuff(int32 Num);
UFUNCTION(BlueprintCallable)
void SendToOtherBuff(int32 Num);
UFUNCTION(BlueprintCallable)
void UseMana(float UsedManaValue);
FORCEINLINE bool IsEmptyMana()
{
return BossMana <= 0;
}
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};반응형
'Unreal5 > 기본개념' 카테고리의 다른 글
| [최적화] 오브젝트 풀링 (6) | 2025.08.02 |
|---|---|
| [설계] BP vs C++ (2) | 2025.06.08 |
| [언리얼5] BP 아이콘 (0) | 2025.02.24 |
| [언리얼5] 라이팅모드 (0) | 2025.02.12 |
| [언리얼5] 기본 최적화 방안 (0) | 2025.02.08 |