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);
}
해당 자료형 들어가서 확인 복사 → 찾기
이것은 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개 뛰어넘어서 그 뒤부터가 파라미터 이다
파라미터 부분 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 . 밑에 콜리전 실린더
overlap하고 Hit를 동시에 출력 클래스 생성
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 이후에 해줘야 한다
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);
};
콜리전 받는 쪽에 충돌체 쪽에
셋팅 해줘야 하는데. 프로젝트 셋팅에서 프리셋 만들어서 주면 된다.
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 로
지수 표시 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 옆에 눌러서 나오는 것들
다이나믹 체크 하면 Event가 사라진다. 다이나믹과 이벤트는 공존 할 수 없다.
RetVal은 Multicast와 Event와 공존할 수 없다.
아무것도 체크 안하면 그냥 일반 델리게이트 이다.
보통 델리게이트 name은 앞에 구조체 처럼 F를 붙인다.
파라미터가 있다면 타입 을 지정 해도 되는데. 넘어간다
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 가 있다.
이것도 C에 정의 되어있다. UGameplayStatics 라고 되어있다. 많이 쓰이니까. Global에 셋팅 이것도 Kismet 에 정의되어있다.
#include "Kismet/GameplayStatics.h"
GetAllActorsOfClass 이동해서 보면
WorldContextObject : 현재 월드를 의미한다고 생각하면된다.
Iterator 문법 이것을 콜론으로 줄여서 사용하는 것이다. : ‘ 요즘엔 이방식을 잘 안쓴다.
이것들을 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) - 모든델리게이트는 이걸 기반으로 한다. )
이렇게 외부 이벤트를 연결해서 상황에 따라 콜 (게임에서 많이 사용) - 때렸을때. 사망. 등등
End도 OffLight에 연결 하면 된다.
end 나왔을 때 꺼지는 것