C02_ComponentOverlap.h

#pragma once

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

UCLASS()
class U2110_03_API AC02_ComponentOverlap : public AActor
{
	GENERATED_BODY()
	
private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Root;

	UPROPERTY(VisibleDefaultsOnly)
		class UBoxComponent* Box;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC02_ComponentOverlap();

protected:
	virtual void BeginPlay() override;

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

	UFUNCTION()
		void OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
};

C02_ComponentOverlap.cpp

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

AC02_ComponentOverlap::AC02_ComponentOverlap()
{
	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 AC02_ComponentOverlap::BeginPlay()
{
	Super::BeginPlay();

	Box->OnComponentBeginOverlap.AddDynamic(this, &AC02_ComponentOverlap::OnComponentBeginOverlap);
	Box->OnComponentEndOverlap.AddDynamic(this, &AC02_ComponentOverlap::OnComponentEndOverlap);
}

void AC02_ComponentOverlap::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
	FString str;
	str.Append("Begin Overlap Component : ");
	str.Append(OverlappedComponent->GetName());
	CLog::Log(str);

	str = "";
	str.Append("Other Actor : ");
	str.Append(OtherActor->GetName());
	CLog::Log(str);

	str = "";
	str.Append("Other Actor : ");
	str.Append(OtherComp->GetName());
	CLog::Log(str);
}

void AC02_ComponentOverlap::OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	FString str;
	str.Append("End Overlap Component : ");
	str.Append(OverlappedComponent->GetName());
	CLog::Log(str);

	str = "";
	str.Append("Other Actor : ");
	str.Append(OtherActor->GetName());
	CLog::Log(str);

	str = "";
	str.Append("Other Actor : ");
	str.Append(OtherComp->GetName());
	CLog::Log(str);
}

해당 자료형 들어가서 확인 복사 → 찾기

Untitled

Untitled

Untitled

이것은 SixParms 라고 6개의 파라미터가 있는 것이다.

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams( FComponentBeginOverlapSignature, UPrimitiveComponent, OnComponentBeginOverlap, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);

해당 이 start라면 3개 뛰어넘어서 그 뒤부터가 파라미터 이다

Untitled

Untitled

 파라미터 부분 UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult

파라미터 부분 UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult

뒤 복사 해서 C02_ComponentOverlap.h에 넣기

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

	UFUNCTION()
		void OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
};

cpp에서 정의

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

void AC03_OverlapAndHit::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
	CLog::Print("BeginOverlap :" + OtherActor->GetName());
}

void AC03_OverlapAndHit::OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	CLog::Print("EndOverlap :" + OtherActor->GetName());
}

void AC03_OverlapAndHit::OnComponentHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	CLog::Print("Hit :" + OtherActor->GetName());
}

OnComponentBeginOverlap : 블루프린트에서 콜리전 생성 한 것과 비슷한 것 이다. (이게 충돌할 것 )

블프에서 다루었던 것을 다뤄보는 것

충돌한 것 :Box  충돌 받은 것 : Player . 밑에 콜리전 실린더

충돌한 것 :Box 충돌 받은 것 : Player . 밑에 콜리전 실린더

Untitled

overlap하고 Hit를 동시에 출력 클래스 생성

Untitled

C03_OverlapAndHit.h

#pragma once

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

UCLASS()
class U2110_03_API AC03_OverlapAndHit : public AActor
{
	GENERATED_BODY()
	
private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Root;

	UPROPERTY(VisibleDefaultsOnly)
		class UBoxComponent* Box;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC03_OverlapAndHit();

protected:
	virtual void BeginPlay() override;

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

	UFUNCTION()
		void OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

	UFUNCTION()
		void OnComponentHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
};

C03_OverlapAndHit.cpp

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

AC03_OverlapAndHit::AC03_OverlapAndHit()
{
	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 AC03_OverlapAndHit::BeginPlay()
{
	Super::BeginPlay();
	
	Box->OnComponentBeginOverlap.AddDynamic(this, &AC03_OverlapAndHit::OnComponentBeginOverlap);
	Box->OnComponentEndOverlap.AddDynamic(this, &AC03_OverlapAndHit::OnComponentEndOverlap);
	Box->OnComponentHit.AddDynamic(this, &AC03_OverlapAndHit::OnComponentHit);
}

void AC03_OverlapAndHit::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult)
{
	CLog::Print("BeginOverlap :" + OtherActor->GetName());
}

void AC03_OverlapAndHit::OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	CLog::Print("EndOverlap :" + OtherActor->GetName());
}

void AC03_OverlapAndHit::OnComponentHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	CLog::Print("Hit :" + OtherActor->GetName());

델리게이션 연결은 반드시 게임이벤트 라서 Beginplay 이후에 해줘야 한다

델리게이션 연결은 반드시 게임이벤트 라서 Beginplay 이후에 해줘야 한다

Box에는 또하나의 성질 Hit

Box->OnComponentHit.AddDynamic(this, &AC03_OverlapAndHit::OnComponentHit);
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_FiveParams( FComponentHitSignature, UPrimitiveComponent, OnComponentHit, UPrimitiveComponent*, HitComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, FVector, NormalImpulse, const FHitResult&, Hit );

NormalImpulse : 충돌받은 단계

FHitResult : 충돌 했을 때

헤더에 생성 후 정의

UFUNCTION()
		void OnComponentHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
};

Untitled

콜리전 받는 쪽에 충돌체 쪽에

Untitled

셋팅 해줘야 하는데. 프로젝트 셋팅에서 프리셋 만들어서 주면 된다.

Box 콜리전

받는 콜리전 박스 셋팅 해줘야한다.  히트는 이벤트가 정의된 쪽을 켜주는 것이다

받는 콜리전 박스 셋팅 해줘야한다. 히트는 이벤트가 정의된 쪽을 켜주는 것이다

들어가면 자기 히트도 발생한다.

들어가면 자기 히트도 발생한다.

히트는 이벤트가 정의된 쪽을 켜준다.

overlap은 양쪽다 켜주는게 좋다.

이벤트를 만들어 볼 것이다. 델리게이트를 만들어 볼 것이다. Light생성

C04_Light.h

#pragma once

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

UCLASS()
class U2110_03_API AC04_Light : public AActor
{
	GENERATED_BODY()
	
private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Root;

	UPROPERTY(VisibleDefaultsOnly)
		class UPointLightComponent* PointLight;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC04_Light();

protected:
	virtual void BeginPlay() override;

private:
	UFUNCTION()
		void OnLight();

	UFUNCTION()
		void OffLight();
};

C04_Light.cpp

#include "C04_Light.h"
#include "Global.h"
#include "Components/PointLightComponent.h"
#include "Components/TextRenderComponent.h"
#include "C04_Trigger.h"

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

	PointLight->SetRelativeLocation(FVector(0, -50, 0));
	PointLight->LightColor = FColor::Red;
	PointLight->Intensity = 1e+4f; //1 * 10 ^ 4
	PointLight->AttenuationRadius = 200;

	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 AC04_Light::BeginPlay()
{
	Super::BeginPlay();

	PointLight->SetVisibility(false);

	//for (AActor* actor : GetWorld()->GetCurrentLevel()->Actors)
	//{
	//	if (!!actor && actor->IsA<AC04_Trigger>())
	//		CLog::Log(actor->GetName());
	//}

	AC04_Trigger* trigger = CHelpers::FindActor<AC04_Trigger>(GetWorld());
	//CLog::Log(trigger);
	if (!!trigger)
	{
		trigger->OnBoxLightBeginOverlap.BindUFunction(this, "OnLight");
		trigger->OnBoxLightEndOverlap.BindUFunction(this, "OffLight");
	}
}

void AC04_Light::OnLight()
{
	PointLight->SetVisibility(true);
}

void AC04_Light::OffLight()
{
	PointLight->SetVisibility(false);
}

PointLightComponent 로

Untitled

지수 표시 10^4 = 10000

지수 표시 10^4 = 10000

C04_Light.h 함수 생

private:
	UFUNCTION()
		void OnLight();

	UFUNCTION()
		void OffLight();

C04_Light.cpp

void AC04_Light::OnLight()
{
	PointLight->SetVisibility(true);
}

void AC04_Light::OffLight()
{
	PointLight->SetVisibility(false);
}

Light를 킬 트리거 이벤트를 발생시킬 것을 만든다.

C04_Trigger.h

#pragma once

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

DECLARE_DELEGATE(FBoxLightOverlap); //void ___()

UCLASS()
class U2110_03_API AC04_Trigger : public AActor
{
	GENERATED_BODY()
	
private:
	UPROPERTY(VisibleDefaultsOnly)
		class USceneComponent* Root;

	UPROPERTY(VisibleDefaultsOnly)
		class UBoxComponent* Box;

	UPROPERTY(VisibleDefaultsOnly)
		class UTextRenderComponent* Text;

public:	
	AC04_Trigger();

protected:
	virtual void BeginPlay() override;

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

	UFUNCTION()
		void OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

public:
	FBoxLightOverlap OnBoxLightBeginOverlap;
};

C04_Trigger.cpp

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

AC04_Trigger::AC04_Trigger()
{
	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 AC04_Trigger::BeginPlay()
{
	Super::BeginPlay();
	
	Box->OnComponentBeginOverlap.AddDynamic(this, &AC04_Trigger::OnComponentBeginOverlap);
	Box->OnComponentEndOverlap.AddDynamic(this, &AC04_Trigger::OnComponentEndOverlap);
}

void AC04_Trigger::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (OnBoxLightBeginOverlap.IsBound())
		OnBoxLightBeginOverlap.Execute();
}

void AC04_Trigger::OnComponentEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{

}

델리게이트

일반 델리게이트 : C내부에서맨

다이나믹 델리게이트는 : 블프에다 공개해줄 수 있다. 이벤트들 Box 옆에 눌러서 나오는 것들

Untitled

Untitled

다이나믹 체크 하면 Event가 사라진다. 다이나믹과 이벤트는 공존 할 수 없다.

Untitled

RetVal은 Multicast와 Event와 공존할 수 없다.

Untitled

아무것도 체크 안하면 그냥 일반 델리게이트 이다.

보통 델리게이트 name은 앞에 구조체 처럼 F를 붙인다.

파라미터가 있다면 타입 을 지정 해도 되는데. 넘어간다

Untitled

DECLARE_DELEGATE(FBoxLightOverlap); //void ___()

함수연결이 리턴형이 void형이고, 함수명이 나오고 파라미터가 아무것도 없는 함수 , 이벤트를 딱 하나만 연결 받을 수 있다.(single)

public:
	FBoxLightOverlap OnBoxLightBeginOverlap; //자료형.On 붙이고 뒤에 비슷하게 넣어서 안헷갈리게

C04_Trigger.cpp

void AC04_Trigger::OnComponentBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (OnBoxLightBeginOverlap.IsBound())
		OnBoxLightBeginOverlap.Execute();
}

겹침 이 시작 되었을떄. IsBound 연결된 함수가 있는가. 연결된 것이 있다면Execute실행 (True리턴) - 함수를 어디선가 연결해줘야 한다. 04_Light로 가서 actor를 찾아줄 것이다.

C04_Light

Actor를 찾기 위한 방식 GetWorld(World를 총괄하는 (현재 열려있는. 레벨을 가져오는 방법은 GetCurrentLevel

for (AActor* actor : GetWorld()->GetCurrentLevel()->Actors) // ':'(반복자) 콜론 이 이터레이션 옮기는 것 
	{
		if (!!actor && actor->IsA<AC04_Trigger>()) //찾고자 하는것 null체크를 해줘야한다. 안하면 다 찾아와버린다.
			CLog::Log(actor->GetName());
	}

다른 찾는 방법은 . 블루프린트에서 보면 Get All Actors Of Class 가 있다.

Untitled

Untitled

이것도 C에 정의 되어있다. UGameplayStatics 라고 되어있다. 많이 쓰이니까. Global에 셋팅 이것도 Kismet 에 정의되어있다.

#include "Kismet/GameplayStatics.h"

GetAllActorsOfClass 이동해서 보면

Untitled

WorldContextObject : 현재 월드를 의미한다고 생각하면된다.

Iterator 문법 이것을 콜론으로 줄여서 사용하는 것이다. : ‘ 요즘엔 이방식을 잘 안쓴다.

Untitled

이것들을 Helpers에서 만들어서 사용할 것이다.


//리턴형
template<typename T>
	static T* FindActor(UWorld* World)
	{
		for (AActor* actor : World->GetCurrentLevel()->Actors)
		{
			if (!!actor && actor->IsA<T>())
				return Cast<T>(actor); //캐스팅 
		}

		return nullptr; //못 찾았을 때 
	}

//Void 형 
	template<typename T>
	static void FindActors(UWorld* World, TArray<T *> OutArray)
	{ // 동일한 것들을 배열로 모아둔 것 
		OutArray.Empty();

		for (AActor* actor : World->GetCurrentLevel()->Actors)
		{
			if (!!actor && actor->IsA<T>())
				OutArray.Add(Cast<T>(actor)); //채워짐 
		}
	}

04_Light.cpp - 기존 것을 제외하고 만들어서

AC04_Trigger* trigger = CHelpers::FindActor<AC04_Trigger>(GetWorld());
	//CLog::Log(trigger); //연결 확인 
	if (!!trigger)
	{
		trigger->OnBoxLightBeginOverlap.BindUFunction(this, "OnLight"); //연결
	}

BindUFunction : 다이나믹 하고 일반이랑 연결하는 방법이 다르다. 싱글 하나 연결 할때는 이것을 사용한다. (UFUNCTION) - 모든델리게이트는 이걸 기반으로 한다. )

이렇게 외부 이벤트를 연결해서 상황에 따라 콜 (게임에서 많이 사용) - 때렸을때. 사망. 등등

Untitled

End도 OffLight에 연결 하면 된다.

Untitled

Untitled

end 나왔을 때 꺼지는 것