Adventure of 빠타박스
article thumbnail
728x90
728x90
SMALL

Unreal Engine 4 /4.26버전으로 수업을 진행합니다. 해당 내용은 수업에 대한 내용과 함께 

개인적인 생각 및 정보를 토대로 글을 씀을 알립니다. 

본 내용에 대하여 상업적으로 이용 및 배포를 금합니다.

이전내용) https://ppatabox.tistory.com/132

 

노션에서 보기 

https://ppatabox.notion.site/UEC-_13_Deligate_ExplosionParticle-c7b9b015a3fa4dad946756c77805db01


UEC_13_Deligate_ExplosionParticle.pdf
0.28MB

델리게이트 :

class A 
	On Changed; // (어떠한 델리게이트)  외부에서 바인딩 OnChanged.BindUFuncition 
	if(IsBound())
		OnChanged.Execute();
}

멀티캐스트 : 블프에 공개는 안되고 프로그램 내부적으로만 사용하는 것 어느 클래스든 이벤트 바인딩이 가능은 하지만. Broadcast, IsBound, Clear(연결된 것 해제) 함수를 출력할 수 있다. ( 지금 클래스 A 안에서만 가능하다는 것) 델리게이션은 클래스 내 말고도 다른 클래스에 있어도 된다. 이벤트가 그것들을 제약해준다.

기준을 블루프린트에 공개할 거면 다이나믹 멀티캐스트 델리게이트를 사용하고

프로그래머들 외부에 공개할 때 프로그래머는 내부 소스를 볼 테고 다이나믹 델리게이트를 해두면 , 내가 호출 해도 되는가 보다 라고 생각하게 된다(프로그래머는 내부 코드를 알고 있는 상태이다.) 그런데 그걸 내부적으로 실행하면 안되는 것이라고 하면 Event로 제약을 시켜주는 것이다.

파생된 클래스는 베이스 클래스의 민감한 이벤트 멤버에 대한 접근권까지 상속하지 않습니다. 그 대신, 파생된 클래스에서도 자신의 이벤트 브로드캐스트를 허용하려는 베이스 클래스는, 이벤트에 대한 protected Broadcast 함수를 노출시켜 줘야 한다.

ex : class A에다 어떠한 이벤트를 만들었다 했을때. 이 이벤트에 대한 IsBound나 Broadcast, clrear 같은 것들이 이 클래스내에서만 사용을 못한다. 이것들은 자신의 클래스를 가지니까. 상속받은 자식의 클래스가 아닌 것이다. 그래서 원칙적으로 B클래스가 있다면 그곳에 공유를 못한다.

그런데 그럼에도 불과 하고 B에서도 콜을 해야할 경우가 있을 것이다. 이럴때

public:
/** 레이어 변경이 있을 때마다 브로드캐스트 */
DECLARE_EVENT( FLayerViewModel, FChangedEvent )
FChangedEvent& OnChanged() { return ChangedEvent; }

protected: //이부분을 통해서 아래 ChangedEvent을 콜을 해준다. (콜할 함수를 하나더 만들어 주는셈)
void BroadcastChanged()
{
    ChangedEvent.Broadcast();
}

private:
/** 레이어 변경이 있을 때마다 브로드캐스트 */
FChangedEvent ChangedEvent; //델리게이트인 이형태함수를 protected Broadcast 함수를 노출시켜 줘야 합니다

ChangedEvent를 위 Protected처럼 하나를 더 만들어서 그것을 통해서 private에 있는 것을 콜하기 시작하게 한다. 자기 자신은 접근이 가능

폭발 효과 나타낼 트리거 (뇌관 같은)

C06_EventTrigger.h

#pragma once

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

UCLASS()
class U2110_03_API AC06_EventTrigger : public AActor
{
	GENERATED_BODY()

private:
	DECLARE_EVENT_OneParam(AC06_EventTrigger, FExplosionEvent, int32);

private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Root;

	UPROPERTY(VisibleDefaultsOnly)
		class UBoxComponent* Box;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC06_EventTrigger();

protected:
	virtual void BeginPlay() override;

private:
	UFUNCTION()
		void OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
public:
	FExplosionEvent OnExplosionEvent;

};

DECLARE_MULTICAST_DELEGATE 이런식으로 클래스 위에 있으면 프로그램 전역에서 사용할 수 있다. (이 헤더만 추가하면)

DECLARE_EVENT_OneParam 그러나 이벤트는 클래스 내부에 정의를 한다. 이클래스에 종속 되기 때문에.

이 이벤트가 이 클래스 내에서 정의 되긴 하지만 어떤 클래스에 대한 이벤트 인가.라는 것을 정의 해줘야한다.

DECLARE_EVENT_OneParam(AC06_EventTrigger, FExplosionEvent, int32);

ex) 이걸 다이나믹 이라고 하는데 안된다. (뒤에 파라미터가 들어가야 다이나믹 ) - 직렬화 때문이다.

DECLARE_EVENT_OneParam(AC06_EventTrigger, FExplosionEvent, int32, parameter);

그래서 Event가 Dynamic속성 못가지고, 이거 자체가 멀티캐스트 이기 때문에 멀티캐스트도 사라지고, 멀티캐스트 일때는 ReturnValue가 없다는 것

C06_EventTrigger.cpp

#include "C06_EventTrigger.h"
#include "Global.h"
#include "Components/BoxComponent.h"
#include "Components/TextRenderComponent.h"

AC06_EventTrigger::AC06_EventTrigger()
{
	CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
	CHelpers::CreateComponent<UBoxComponent>(this, &Box, "Box", Root);
	CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Text", Root);

	Box->SetRelativeScale3D(FVector(3));
	Box->bHiddenInGame = false;

	Text->SetRelativeLocation(FVector(0, 0, 100));
	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeScale3D(FVector(2));
	Text->TextRenderColor = FColor::Red;
	Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;
	Text->Text = FText::FromString(GetName().Replace(L"Default__", L""));

}

void AC06_EventTrigger::BeginPlay()
{
	Super::BeginPlay();
	
	Box->OnComponentBeginOverlap.AddDynamic(this, &AC06_EventTrigger::OnComponentBeginOverlap);
}

void AC06_EventTrigger::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	CheckFalse(OnExplosionEvent.IsBound());

	int32 index = UKismetMathLibrary::RandomIntegerInRange(0, 2);
	OnExplosionEvent.Broadcast(index);
}

폭발 효과 이펙트

C06_Explosion.h

#pragma once

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

UCLASS()
class U2110_03_API AC06_Explosion : public AActor
{
	GENERATED_BODY()
	

private:
	UPROPERTY(EditAnywhere, Category = "Particle")
		class UParticleSystem* Particles[3];

private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Root;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC06_Explosion();

protected:
	virtual void BeginPlay() override;

private:
	UFUNCTION()
		void OnExplostion(int32 InIndex);
};

C06_Explosion.cpp

#include "C06_Explosion.h"
#include "Global.h"
#include "C06_EventTrigger.h"
#include "Components/BoxComponent.h"
#include "Components/TextRenderComponent.h"
#include "Particles/ParticleSystem.h"

AC06_Explosion::AC06_Explosion()
{
	CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
	CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Text", Root);

	Text->SetRelativeLocation(FVector(0, 0, 100));
	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeScale3D(FVector(2));
	Text->TextRenderColor = FColor::Red;
	Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;
	Text->Text = FText::FromString(GetName().Replace(L"Default__", L""));

	CHelpers::GetAsset<UParticleSystem>(&Particles[0], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_00'");
	CHelpers::GetAsset<UParticleSystem>(&Particles[1], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_01'");
	CHelpers::GetAsset<UParticleSystem>(&Particles[2], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_03'");
}

void AC06_Explosion::BeginPlay()
{
	Super::BeginPlay();
	
	AC06_EventTrigger* trigger = CHelpers::FindActor< AC06_EventTrigger>(GetWorld());
	CheckNull(trigger);

	trigger->OnExplosionEvent.AddUFunction(this, "OnExplostion");
}

void AC06_Explosion::OnExplostion(int32 InIndex)
{
	UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), Particles[InIndex], GetActorLocation());
}

파티클 경로 따오기

CHelpers::GetAsset<UParticleSystem>(&Particles[0], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_00'");
CHelpers::GetAsset<UParticleSystem>(&Particles[1], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_01'");
CHelpers::GetAsset<UParticleSystem>(&Particles[2], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_03'");

파티클 시스템 있는 곳

#include "Particles/ParticleSystem.h

플레이 Begin할때 Trigger찾아오기

void AC06_Explosion::BeginPlay()
{
	Super::BeginPlay();
	
	AC06_EventTrigger* trigger = CHelpers::FindActor< AC06_EventTrigger>(GetWorld());
	CheckNull(trigger);

	trigger->OnExplosionEvent.AddUFunction(this, "OnExplostion");
}
class A 
	On Changed; // (어떠한 델리게이트)  외부에서 바인딩 OnChanged.BindUFuncition 
	if(IsBound())
		OnChanged.Execute();
}

멀티캐스트 : 블프에 공개는 안되고 프로그램 내부적으로만 사용하는 것 어느 클래스든 이벤트 바인딩이 가능은 하지만. Broadcast, IsBound, Clear(연결된 것 해제) 함수를 출력할 수 있다. ( 지금 클래스 A 안에서만 가능하다는 것) 델리게이션은 클래스 내 말고도 다른 클래스에 있어도 된다. 이벤트가 그것들을 제약해준다.

기준을 블루프린트에 공개할 거면 다이나믹 멀티캐스트 델리게이트를 사용하고

프로그래머들 외부에 공개할 때 프로그래머는 내부 소스를 볼 테고 다이나믹 델리게이트를 해두면 , 내가 호출 해도 되는가 보다 라고 생각하게 된다(프로그래머는 내부 코드를 알고 있는 상태이다.) 그런데 그걸 내부적으로 실행하면 안되는 것이라고 하면 Event로 제약을 시켜주는 것이다.

파생된 클래스는 베이스 클래스의 민감한 이벤트 멤버에 대한 접근권까지 상속하지 않습니다. 그 대신, 파생된 클래스에서도 자신의 이벤트 브로드캐스트를 허용하려는 베이스 클래스는, 이벤트에 대한 protected Broadcast 함수를 노출시켜 줘야 한다.

ex : class A에다 어떠한 이벤트를 만들었다 했을때. 이 이벤트에 대한 IsBound나 Broadcast, clrear 같은 것들이 이 클래스내에서만 사용을 못한다. 이것들은 자신의 클래스를 가지니까. 상속받은 자식의 클래스가 아닌 것이다. 그래서 원칙적으로 B클래스가 있다면 그곳에 공유를 못한다.

그런데 그럼에도 불과 하고 B에서도 콜을 해야할 경우가 있을 것이다. 이럴때

public:
/** 레이어 변경이 있을 때마다 브로드캐스트 */
DECLARE_EVENT( FLayerViewModel, FChangedEvent )
FChangedEvent& OnChanged() { return ChangedEvent; }

protected: //이부분을 통해서 아래 ChangedEvent을 콜을 해준다. (콜할 함수를 하나더 만들어 주는셈)
void BroadcastChanged()
{
    ChangedEvent.Broadcast();
}

private:
/** 레이어 변경이 있을 때마다 브로드캐스트 */
FChangedEvent ChangedEvent; //델리게이트인 이형태함수를 protected Broadcast 함수를 노출시켜 줘야 합니다

ChangedEvent를 위 Protected처럼 하나를 더 만들어서 그것을 통해서 private에 있는 것을 콜하기 시작하게 한다. 자기 자신은 접근이 가능

폭발 효과 나타낼 트리거 (뇌관 같은)

C06_EventTrigger.h

#pragma once

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

UCLASS()
class U2110_03_API AC06_EventTrigger : public AActor
{
	GENERATED_BODY()

private:
	DECLARE_EVENT_OneParam(AC06_EventTrigger, FExplosionEvent, int32);

private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Root;

	UPROPERTY(VisibleDefaultsOnly)
		class UBoxComponent* Box;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC06_EventTrigger();

protected:
	virtual void BeginPlay() override;

private:
	UFUNCTION()
		void OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
public:
	FExplosionEvent OnExplosionEvent;

};

DECLARE_MULTICAST_DELEGATE 이런식으로 클래스 위에 있으면 프로그램 전역에서 사용할 수 있다. (이 헤더만 추가하면)

DECLARE_EVENT_OneParam 그러나 이벤트는 클래스 내부에 정의를 한다. 이클래스에 종속 되기 때문에.

이 이벤트가 이 클래스 내에서 정의 되긴 하지만 어떤 클래스에 대한 이벤트 인가.라는 것을 정의 해줘야한다.

DECLARE_EVENT_OneParam(AC06_EventTrigger, FExplosionEvent, int32);

ex) 이걸 다이나믹 이라고 하는데 안된다. (뒤에 파라미터가 들어가야 다이나믹 ) - 직렬화 때문이다.

DECLARE_EVENT_OneParam(AC06_EventTrigger, FExplosionEvent, int32, parameter);

그래서 Event가 Dynamic속성 못가지고, 이거 자체가 멀티캐스트 이기 때문에 멀티캐스트도 사라지고, 멀티캐스트 일때는 ReturnValue가 없다는 것

C06_EventTrigger.cpp

#include "C06_EventTrigger.h"
#include "Global.h"
#include "Components/BoxComponent.h"
#include "Components/TextRenderComponent.h"

AC06_EventTrigger::AC06_EventTrigger()
{
	CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
	CHelpers::CreateComponent<UBoxComponent>(this, &Box, "Box", Root);
	CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Text", Root);

	Box->SetRelativeScale3D(FVector(3));
	Box->bHiddenInGame = false;

	Text->SetRelativeLocation(FVector(0, 0, 100));
	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeScale3D(FVector(2));
	Text->TextRenderColor = FColor::Red;
	Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;
	Text->Text = FText::FromString(GetName().Replace(L"Default__", L""));

}

void AC06_EventTrigger::BeginPlay()
{
	Super::BeginPlay();
	
	Box->OnComponentBeginOverlap.AddDynamic(this, &AC06_EventTrigger::OnComponentBeginOverlap);
}

void AC06_EventTrigger::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	CheckFalse(OnExplosionEvent.IsBound());

	int32 index = UKismetMathLibrary::RandomIntegerInRange(0, 2);
	OnExplosionEvent.Broadcast(index);
}

폭발 효과 이펙트

C06_Explosion.h

#pragma once

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

UCLASS()
class U2110_03_API AC06_Explosion : public AActor
{
	GENERATED_BODY()
	

private:
	UPROPERTY(EditAnywhere, Category = "Particle")
		class UParticleSystem* Particles[3];

private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Root;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC06_Explosion();

protected:
	virtual void BeginPlay() override;

private:
	UFUNCTION()
		void OnExplostion(int32 InIndex);
};

C06_Explosion.cpp

#include "C06_Explosion.h"
#include "Global.h"
#include "C06_EventTrigger.h"
#include "Components/BoxComponent.h"
#include "Components/TextRenderComponent.h"
#include "Particles/ParticleSystem.h"

AC06_Explosion::AC06_Explosion()
{
	CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
	CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Text", Root);

	Text->SetRelativeLocation(FVector(0, 0, 100));
	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeScale3D(FVector(2));
	Text->TextRenderColor = FColor::Red;
	Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;
	Text->Text = FText::FromString(GetName().Replace(L"Default__", L""));

	CHelpers::GetAsset<UParticleSystem>(&Particles[0], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_00'");
	CHelpers::GetAsset<UParticleSystem>(&Particles[1], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_01'");
	CHelpers::GetAsset<UParticleSystem>(&Particles[2], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_03'");
}

void AC06_Explosion::BeginPlay()
{
	Super::BeginPlay();
	
	AC06_EventTrigger* trigger = CHelpers::FindActor< AC06_EventTrigger>(GetWorld());
	CheckNull(trigger);

	trigger->OnExplosionEvent.AddUFunction(this, "OnExplostion");
}

void AC06_Explosion::OnExplostion(int32 InIndex)
{
	UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), Particles[InIndex], GetActorLocation());
}

파티클 경로 따오기

CHelpers::GetAsset<UParticleSystem>(&Particles[0], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_00'");
CHelpers::GetAsset<UParticleSystem>(&Particles[1], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_01'");
CHelpers::GetAsset<UParticleSystem>(&Particles[2], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_03'");

파티클 시스템 있는 곳

#include "Particles/ParticleSystem.h

플레이 Begin할때 Trigger찾아오기

void AC06_Explosion::BeginPlay()
{
	Super::BeginPlay();
	
	AC06_EventTrigger* trigger = CHelpers::FindActor< AC06_EventTrigger>(GetWorld());
	CheckNull(trigger);

	trigger->OnExplosionEvent.AddUFunction(this, "OnExplostion");
}
class A 
	On Changed; // (어떠한 델리게이트)  외부에서 바인딩 OnChanged.BindUFuncition 
	if(IsBound())
		OnChanged.Execute();
}

멀티캐스트 : 블프에 공개는 안되고 프로그램 내부적으로만 사용하는 것 어느 클래스든 이벤트 바인딩이 가능은 하지만. Broadcast, IsBound, Clear(연결된 것 해제) 함수를 출력할 수 있다. ( 지금 클래스 A 안에서만 가능하다는 것) 델리게이션은 클래스 내 말고도 다른 클래스에 있어도 된다. 이벤트가 그것들을 제약해준다.

기준을 블루프린트에 공개할 거면 다이나믹 멀티캐스트 델리게이트를 사용하고

프로그래머들 외부에 공개할 때 프로그래머는 내부 소스를 볼 테고 다이나믹 델리게이트를 해두면 , 내가 호출 해도 되는가 보다 라고 생각하게 된다(프로그래머는 내부 코드를 알고 있는 상태이다.) 그런데 그걸 내부적으로 실행하면 안되는 것이라고 하면 Event로 제약을 시켜주는 것이다.

파생된 클래스는 베이스 클래스의 민감한 이벤트 멤버에 대한 접근권까지 상속하지 않습니다. 그 대신, 파생된 클래스에서도 자신의 이벤트 브로드캐스트를 허용하려는 베이스 클래스는, 이벤트에 대한 protected Broadcast 함수를 노출시켜 줘야 한다.

ex : class A에다 어떠한 이벤트를 만들었다 했을때. 이 이벤트에 대한 IsBound나 Broadcast, clrear 같은 것들이 이 클래스내에서만 사용을 못한다. 이것들은 자신의 클래스를 가지니까. 상속받은 자식의 클래스가 아닌 것이다. 그래서 원칙적으로 B클래스가 있다면 그곳에 공유를 못한다.

그런데 그럼에도 불과 하고 B에서도 콜을 해야할 경우가 있을 것이다. 이럴때

public:
/** 레이어 변경이 있을 때마다 브로드캐스트 */
DECLARE_EVENT( FLayerViewModel, FChangedEvent )
FChangedEvent& OnChanged() { return ChangedEvent; }

protected: //이부분을 통해서 아래 ChangedEvent을 콜을 해준다. (콜할 함수를 하나더 만들어 주는셈)
void BroadcastChanged()
{
    ChangedEvent.Broadcast();
}

private:
/** 레이어 변경이 있을 때마다 브로드캐스트 */
FChangedEvent ChangedEvent; //델리게이트인 이형태함수를 protected Broadcast 함수를 노출시켜 줘야 합니다

ChangedEvent를 위 Protected처럼 하나를 더 만들어서 그것을 통해서 private에 있는 것을 콜하기 시작하게 한다. 자기 자신은 접근이 가능

폭발 효과 나타낼 트리거 (뇌관 같은)

C06_EventTrigger.h

#pragma once

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

UCLASS()
class U2110_03_API AC06_EventTrigger : public AActor
{
	GENERATED_BODY()

private:
	DECLARE_EVENT_OneParam(AC06_EventTrigger, FExplosionEvent, int32);

private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Root;

	UPROPERTY(VisibleDefaultsOnly)
		class UBoxComponent* Box;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC06_EventTrigger();

protected:
	virtual void BeginPlay() override;

private:
	UFUNCTION()
		void OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
public:
	FExplosionEvent OnExplosionEvent;

};

DECLARE_MULTICAST_DELEGATE 이런식으로 클래스 위에 있으면 프로그램 전역에서 사용할 수 있다. (이 헤더만 추가하면)

DECLARE_EVENT_OneParam 그러나 이벤트는 클래스 내부에 정의를 한다. 이클래스에 종속 되기 때문에.

이 이벤트가 이 클래스 내에서 정의 되긴 하지만 어떤 클래스에 대한 이벤트 인가.라는 것을 정의 해줘야한다.

DECLARE_EVENT_OneParam(AC06_EventTrigger, FExplosionEvent, int32);

ex) 이걸 다이나믹 이라고 하는데 안된다. (뒤에 파라미터가 들어가야 다이나믹 ) - 직렬화 때문이다.

DECLARE_EVENT_OneParam(AC06_EventTrigger, FExplosionEvent, int32, parameter);

그래서 Event가 Dynamic속성 못가지고, 이거 자체가 멀티캐스트 이기 때문에 멀티캐스트도 사라지고, 멀티캐스트 일때는 ReturnValue가 없다는 것

C06_EventTrigger.cpp

#include "C06_EventTrigger.h"
#include "Global.h"
#include "Components/BoxComponent.h"
#include "Components/TextRenderComponent.h"

AC06_EventTrigger::AC06_EventTrigger()
{
	CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
	CHelpers::CreateComponent<UBoxComponent>(this, &Box, "Box", Root);
	CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Text", Root);

	Box->SetRelativeScale3D(FVector(3));
	Box->bHiddenInGame = false;

	Text->SetRelativeLocation(FVector(0, 0, 100));
	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeScale3D(FVector(2));
	Text->TextRenderColor = FColor::Red;
	Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;
	Text->Text = FText::FromString(GetName().Replace(L"Default__", L""));

}

void AC06_EventTrigger::BeginPlay()
{
	Super::BeginPlay();
	
	Box->OnComponentBeginOverlap.AddDynamic(this, &AC06_EventTrigger::OnComponentBeginOverlap);
}

void AC06_EventTrigger::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	CheckFalse(OnExplosionEvent.IsBound());

	int32 index = UKismetMathLibrary::RandomIntegerInRange(0, 2);
	OnExplosionEvent.Broadcast(index);
}

폭발 효과 이펙트

C06_Explosion.h

#pragma once

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

UCLASS()
class U2110_03_API AC06_Explosion : public AActor
{
	GENERATED_BODY()
	

private:
	UPROPERTY(EditAnywhere, Category = "Particle")
		class UParticleSystem* Particles[3];

private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Root;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC06_Explosion();

protected:
	virtual void BeginPlay() override;

private:
	UFUNCTION()
		void OnExplostion(int32 InIndex);
};

C06_Explosion.cpp

#include "C06_Explosion.h"
#include "Global.h"
#include "C06_EventTrigger.h"
#include "Components/BoxComponent.h"
#include "Components/TextRenderComponent.h"
#include "Particles/ParticleSystem.h"

AC06_Explosion::AC06_Explosion()
{
	CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
	CHelpers::CreateComponent<UTextRenderComponent>(this, &Text, "Text", Root);

	Text->SetRelativeLocation(FVector(0, 0, 100));
	Text->SetRelativeRotation(FRotator(0, 180, 0));
	Text->SetRelativeScale3D(FVector(2));
	Text->TextRenderColor = FColor::Red;
	Text->HorizontalAlignment = EHorizTextAligment::EHTA_Center;
	Text->Text = FText::FromString(GetName().Replace(L"Default__", L""));

	CHelpers::GetAsset<UParticleSystem>(&Particles[0], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_00'");
	CHelpers::GetAsset<UParticleSystem>(&Particles[1], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_01'");
	CHelpers::GetAsset<UParticleSystem>(&Particles[2], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_03'");
}

void AC06_Explosion::BeginPlay()
{
	Super::BeginPlay();
	
	AC06_EventTrigger* trigger = CHelpers::FindActor< AC06_EventTrigger>(GetWorld());
	CheckNull(trigger);

	trigger->OnExplosionEvent.AddUFunction(this, "OnExplostion");
}

void AC06_Explosion::OnExplostion(int32 InIndex)
{
	UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), Particles[InIndex], GetActorLocation());
}

파티클 경로 따오기

CHelpers::GetAsset<UParticleSystem>(&Particles[0], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_00'");
CHelpers::GetAsset<UParticleSystem>(&Particles[1], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_01'");
CHelpers::GetAsset<UParticleSystem>(&Particles[2], "ParticleSystem'/Game/M5VFXVOL2/Particles/Explosion/Fire_Exp_00.Fire_Exp_03'");

파티클 시스템 있는 곳

#include "Particles/ParticleSystem.h

플레이 Begin할때 Trigger찾아오기

void AC06_Explosion::BeginPlay()
{
	Super::BeginPlay();
	
	AC06_EventTrigger* trigger = CHelpers::FindActor< AC06_EventTrigger>(GetWorld());
	CheckNull(trigger);

	trigger->OnExplosionEvent.AddUFunction(this, "OnExplostion");
}
728x90
728x90
LIST
profile

Adventure of 빠타박스

@PPATABOX

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!