프로그래밍 공부
작성일
2024. 4. 2. 18:08
작성자
WDmil
728x90

델리게이트의 여러 종류를 알아보자.

델리게이트를 자유롭게 활용하고 쉽게 이용할 수 있어야 한다.


SingleDelegateParam

 

델리게이트에 파라미터를 넣어서 반환시킨다.

 

함수의 인풋값에 임의의 객체값을 기입하고, 해당 함수를 받아와, 델리게이트가 실행될 때 지정된 int값을 넣게된다.

 

.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C06_2_SingleDelegate_B.generated.h"

class UTextRenderComponent;
class USpotLightComponent;

UCLASS()
class SUBPROJECT_API AC06_2_SingleDelegate_B : public AActor
{
	GENERATED_BODY()

	UPROPERTY(VisibleDefaultsOnly)
	USceneComponent* Scene;

	UPROPERTY(VisibleDefaultsOnly)
	UTextRenderComponent* Text;

	UPROPERTY(VisibleDefaultsOnly)
	UParticleSystem* Particles[3];

public:	
	// Sets default values for this actor's properties
	AC06_2_SingleDelegate_B();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:
	UFUNCTION()
	void SwitchParticle(int32 input);
};

 

주요 확인점은, SwitchParticle로, 인풋값으로 int32 input을 받고있다.

// Fill out your copyright notice in the Description page of Project Settings.


#include "C06_2_SingleDelegate_B.h"
#include "C06_1_Delegate.h"

#include "Components/TextRenderComponent.h"
#include "Particles/ParticleSystem.h"
#include "Kismet/GameplayStatics.h"
#include "Utilities/Helper.h"

// Sets default values
AC06_2_SingleDelegate_B::AC06_2_SingleDelegate_B()
{
	Scene = Helper::CreateSceneComponent<USceneComponent>(this, "Scene");
	Text = Helper::CreateSceneComponent<UTextRenderComponent>(this, "Text", Scene);

	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeLocation(FVector(0, 0, 120));
	Text->SetHorizontalAlignment(EHorizTextAligment::EHTA_Center);
	Text->SetVerticalAlignment(EVerticalTextAligment::EVRTA_TextCenter);
	Text->Text = FText::FromString(GetName().Replace(L"Default__", L""));
	Text->SetTextRenderColor(FColor::Yellow);

	Particles[0] = Helper::GetAsset<UParticleSystem>("/Script/Engine.ParticleSystem'/Game/Particles/P_Explosion.P_Explosion'");
	Particles[1] = Helper::GetAsset<UParticleSystem>("/Script/Engine.ParticleSystem'/Game/Particles/P_Explosion1.P_Explosion1'");
	Particles[2] = Helper::GetAsset<UParticleSystem>("/Script/Engine.ParticleSystem'/Game/Particles/P_Explosion2.P_Explosion2'");
}

// Called when the game starts or when spawned
void AC06_2_SingleDelegate_B::BeginPlay()
{
	Super::BeginPlay();
	AC06_1_Delegate* Switch = Helper::GetActor<AC06_1_Delegate>(GetWorld());
	if (Switch)
	{
		Switch->SingleDelegateParam.BindUFunction(this, "SwitchParticle");
	}
	
}

void AC06_2_SingleDelegate_B::SwitchParticle(int32 input)
{
	UGameplayStatics::SpawnEmitterAtLocation(this, Particles[input], GetActorLocation());
}

해당 함수는 input을 받아와서 Particles의 input번째 객체에 대입하여, 지정 위치에 Spawn하는 동작을 가진다.

 

BeginPlay에서 해당 함수를 델리게이터를 확인하여 원하는 델리게이트 이벤트에 넣어준다.

 

테스트


멀티 델리게이트

 

싱글 델리게이트는 원하는 객체의 함수를 한개 씩 밖에 동작시키지 못한다.

그러나, 멀티 델리게이트는 원하는 함수를 여러개 동작시킬 수 있다.

 

어떠한 동작객체가 있을 때, 그 동작을 감지하는 N개의 엑터가 존재할 수 있다는 의미이다.

 

.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C06_3_MultiDelegate.generated.h"

class UTextRenderComponent;
class USpotLightComponent;

UCLASS()
class SUBPROJECT_API AC06_3_MultiDelegate : public AActor
{
	GENERATED_BODY()

	UPROPERTY(VisibleDefaultsOnly)
	USceneComponent* Scene;

	UPROPERTY(VisibleDefaultsOnly)
	UTextRenderComponent* Text;

	UPROPERTY(VisibleDefaultsOnly)
	UParticleSystem* Particles[3];

public:	
	// Sets default values for this actor's properties
	AC06_3_MultiDelegate();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:
	UFUNCTION()
	void SwitchParticle();
};
// Fill out your copyright notice in the Description page of Project Settings.


#include "C06_3_MultiDelegate.h"
#include "C06_1_Delegate.h"

#include "Components/TextRenderComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "Kismet/KismetTextLibrary.h"
#include "Kismet/GameplayStatics.h"
#include "Particles/ParticleSystem.h"
#include "Utilities/Helper.h"

// Sets default values
AC06_3_MultiDelegate::AC06_3_MultiDelegate()
{
	Scene = Helper::CreateSceneComponent<USceneComponent>(this, "Scene");
	Text = Helper::CreateSceneComponent<UTextRenderComponent>(this, "Text", Scene);

	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeLocation(FVector(0, 0, 120));
	Text->SetHorizontalAlignment(EHorizTextAligment::EHTA_Center);
	Text->SetVerticalAlignment(EVerticalTextAligment::EVRTA_TextCenter);
	Text->Text = FText::FromString(GetName().Replace(L"Default__", L""));
	Text->SetTextRenderColor(FColor::Yellow);

	Particles[0] = Helper::GetAsset<UParticleSystem>("/Script/Engine.ParticleSystem'/Game/Particles/P_Explosion.P_Explosion'");
	Particles[1] = Helper::GetAsset<UParticleSystem>("/Script/Engine.ParticleSystem'/Game/Particles/P_Explosion1.P_Explosion1'");
	Particles[2] = Helper::GetAsset<UParticleSystem>("/Script/Engine.ParticleSystem'/Game/Particles/P_Explosion2.P_Explosion2'");

}

// Called when the game starts or when spawned
void AC06_3_MultiDelegate::BeginPlay()
{
	Super::BeginPlay();
	AC06_1_Delegate* Switch = Helper::GetActor<AC06_1_Delegate>(GetWorld());
	if (Switch)
	{
		Switch->MultiDelegate.AddUFunction(this, "SwitchParticle");
	}
}

void AC06_3_MultiDelegate::SwitchParticle()
{
	int32 RandomInt = UKismetMathLibrary::RandomInteger(3);
	Text->SetText(UKismetTextLibrary::Conv_IntToText(RandomInt));

	UGameplayStatics::SpawnEmitterAtLocation(this, Particles[RandomInt], GetActorLocation());
}

 

일반적인 싱글 델리게이터와 함수 구성사항은 같다.

그러나, 델리게이트의 동작을 위해, 함수를 삽입하는 과정에서 AddUFunction을 통해, 지정이 아닌 배열에 집어넣는다는 걸 알 수 있다.

 

 

멀티 델리게이트는

DECLARE_MULTICAST_DELEGATE(FMultiDelegate)

를 통하여 생성, 관리할 수 있다.

	if (MultiDelegate.IsBound())
		MultiDelegate.Broadcast();

유효할 경우, Broadcast()명령을 통하여. 지정된 함수들을 전부 동작시킨다.

 

테스트

 

 

멀티, 싱글 델리게이트는 각 조합하듯. 원하는 델리게이트를 사용할 수 있다.

 

멀티 파라미터 델리게이트 또한 존재함을 잊지말자.

728x90