[UE] Collision(Overlap, hit)
언리얼 C++에서 충돌(Collision)을 다루기 위해서는, 먼저 충돌 검사(Collision Detection)를 해야 한다. 충돌 검사는 물체의 위치와 크기를 고려하여 두 물체가 서로 충돌했는지 여부를 판단하는 것이다. 언리얼 C++에서는 다양한 충돌 검사 방법을 제공한다.
목차
Collision
01_Spawn | |
C01_Properties.h .cpp C02_Mesh C02_Mesh_Sphere C02_Mesh_Cone C03_Spawner.h .cpp |
|
02_Profiler | |
C01_Log.h .cpp C02_DrawDebug.h .cpp |
|
03_Collision | |
C01_ActorOverlap.h .cpp C02_ComponentOverlap.h .cpp 생성 C03_OverlapAndHit.h .cpp 생성 C04_Trigger.h .cpp 생성 C04_Light.h .cpp 생성 |
|
Utilities | |
CHelpers.h | |
CAnimInstance.h .cpp CGameMode.h .cpp CPlayer.h .cpp |
C02_Component Overlap 생성
새 C++ 클래스 - C02_ComponentOverlap 생성
C02_ComponentOverlap.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C02_ComponentOverlap.generated.h"
UCLASS()
class U2212_03_API AC02_ComponentOverlap : public AActor
{
GENERATED_BODY()
private:
UPROPERTY(VisibleAnywhere)
class USceneComponent* Root;
UPROPERTY(VisibleAnywhere)
class UBoxComponent* Box;
UPROPERTY(VisibleAnywhere)
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 "03_Collision/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);
CreateTextRender();
Box->bHiddenInGame = false;
Box->SetRelativeScale3D(FVector(3));
}
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 = "-----Begin-----";
CLog::Log(str);
str = FString::Printf(L"Overlap Component : %s", *OverlappedComponent->GetName());
CLog::Log(str);
str = FString::Printf(L"Other Actor : %s", *OtherActor->GetName());
CLog::Log(str);
str = FString::Printf(L"Other Component : %s", *OtherComp->GetName());
CLog::Log(str);
}
void AC02_ComponentOverlap::OnComponentEndOverlap(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex)
{
FString str;
str = "-----End-----";
CLog::Log(str);
str = FString::Printf(L"Overlap Component : %s", *OverlappedComponent->GetName());
CLog::Log(str);
str = FString::Printf(L"Other Actor : %s", *OtherActor->GetName());
CLog::Log(str);
str = FString::Printf(L"Other Component : %s", *OtherComp->GetName());
CLog::Log(str);
}
BlueprintAssignable: 이벤트를 블루프린트에 공개되게 하는 역할
C03_Overlap And Hit 생성
새 C++ 클래스 - C03_Overlap And Hit 생성
C03_OverlapAndHit.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C03_OverlapAndHit.generated.h"
UCLASS()
class U2212_03_API AC03_OverlapAndHit : public AActor
{
GENERATED_BODY()
private:
UPROPERTY(VisibleAnywhere)
class USceneComponent* Root;
UPROPERTY(VisibleAnywhere)
class UBoxComponent* Box;
UPROPERTY(VisibleAnywhere)
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 "03_Collision/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);
CreateTextRender();
Box->bHiddenInGame = false;
Box->SetRelativeScale3D(FVector(3));
}
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)
{
FString str;
str = FString::Printf(L"Begin Overlap : %s", *OtherActor->GetName());
CLog::Log(str);
}
void AC03_OverlapAndHit::OnComponentEndOverlap(UPrimitiveComponent * OverlappedComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, int32 OtherBodyIndex)
{
FString str;
str = FString::Printf(L"End Overlap : %s", *OtherActor->GetName());
CLog::Log(str);
}
void AC03_OverlapAndHit::OnComponentHit(UPrimitiveComponent * HitComponent, AActor * OtherActor, UPrimitiveComponent * OtherComp, FVector NormalImpulse, const FHitResult & Hit)
{
FString str;
str = FString::Printf(L"Hit : %s", *OtherActor->GetName());
CLog::Log(str);
}
BP_C03_OverlapAndHit
- 피직스- Simulate Physics를 체크하여 큐브가 떨어지도록 설정한다.언리얼 4.25부터 받는쪽을 기준으로 Collision을 연산한다.
- Query only: 겹침(overlap)연산만 수행
- Physics only: 블록(block)연산만 수행
- Collision Enable: 겹침, 블록연산 둘 다 수행
실행화면
Trigger Light
Delegate
결합성을 낮추는 방식으로 관리한다.
SOLID
https://wkdtjsgur100.github.io/solid-principle/
https://www.nextree.co.kr/p6960/
CHelpers.h
CHelpers.h
더보기
#pragma once
#include "CoreMinimal.h"
...
class U2212_03_API CHelpers
{
public:
...
template<typename T>
static T* FindActor(UWorld* InWorld)
{
for (AActor* actor : InWorld->GetCurrentLevel()->Actors)
{
if (!!actor && actor->IsA<T>())
return Cast<T>(actor);
}
return nullptr;
}
template<typename T>
static void FindActors(UWorld* InWorld, TArray<T*>& OutActors)
{
for (AActor* actor : GetWorld()->GetCurrentLevel()->Actors)
{
if (!!actor && actor->IsA<T>())
OutActors.Add(Cast<T>(actor));
}
}
};
C04_Light의 아래의 접힌 코드를 CHelpers.h에서
- static void FindActor(UWorld* InWorld)
- static void FindActors(UWorld* InWorld, TArray<T*>& OutActors)
템플릿화 하였다.
더보기
for (AActor* actor : GetWorld()->GetCurrentLevel()->Actors)
{
if (!!actor && actor->IsA<AC04_Trigger>())
CLog::Log(actor->GetName());
}
C04_Trigger 생성
C04_Trigger.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C04_Trigger.generated.h"
DECLARE_DELEGATE(FBoxLightOverlap); //void func_name()
UCLASS()
class U2212_03_API AC04_Trigger : public AActor
{
GENERATED_BODY()
private:
UPROPERTY(VisibleAnywhere)
class USceneComponent* Root;
UPROPERTY(VisibleAnywhere)
class UBoxComponent* Box;
UPROPERTY(VisibleAnywhere)
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; //이벤트 변수
FBoxLightOverlap OnBoxLightEndOverlap; //이벤트 변수
};
C04_Trigger.cpp
더보기
#include "03_Collision/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);
CreateTextRender();
Box->bHiddenInGame = false;
Box->SetRelativeScale3D(FVector(3));
}
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)
{
if (OnBoxLightEndOverlap.IsBound())
OnBoxLightEndOverlap.Execute();
}
C04_Light 생성
C04_Lightr.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C04_Light.generated.h"
UCLASS()
class U2212_03_API AC04_Light : public AActor
{
GENERATED_BODY()
private:
UPROPERTY(VisibleAnywhere)
class USceneComponent* Root;
UPROPERTY(VisibleAnywhere)
class UPointLightComponent* PointLight;
UPROPERTY(VisibleAnywhere)
class UPointLightComponent* PointLight2;
UPROPERTY(VisibleAnywhere)
class UTextRenderComponent* Text;
public:
AC04_Light();
protected:
virtual void BeginPlay() override;
private:
UFUNCTION()
void OnLight();
UFUNCTION()
void OffLight();
};
C04_Light.cpp
더보기
#include "03_Collision/C04_Light.h"
#include "Global.h"
#include "C04_Trigger.h"
#include "Components/PointLightComponent.h"
#include "Components/TextRenderComponent.h"
AC04_Light::AC04_Light()
{
CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
CHelpers::CreateComponent<UPointLightComponent>(this, &PointLight, "PointLight", Root);
CHelpers::CreateComponent<UPointLightComponent>(this, &PointLight2, "PointLight2", Root);
CreateTextRender();
PointLight->SetRelativeLocation(FVector(0, -50, 0));//Actor로부터의 상대간격
PointLight->LightColor = FColor::Red;
PointLight->Intensity = 1e+4f; //1 * 10 ^ 4
PointLight->AttenuationRadius = 200; //감쇄 반경
PointLight2->SetRelativeLocation(FVector(0, +50, 0));
PointLight2->LightColor = FColor::Red;
PointLight2->Intensity = 1e+4f; //1 * 10 ^ 4
PointLight2->AttenuationRadius = 200; //감쇄 반경
}
void AC04_Light::BeginPlay()
{
Super::BeginPlay();
//for (AActor* actor : GetWorld()->GetCurrentLevel()->Actors)
//{
// if (!!actor && actor->IsA<AC04_Trigger>())
// CLog::Log(actor->GetName());
//}
OffLight();
AC04_Trigger* trigger = CHelpers::FindActor<AC04_Trigger>(GetWorld());
CheckNull(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);
PointLight2->SetVisibility(false);
}
실행화면
'⭐ Unreal Engine > UE FPS TPS' 카테고리의 다른 글
[UE] Collision(Override), BP와 C++ 실행순서 (0) | 2023.03.14 |
---|---|
[UE] Collsion(trigger, MultiTrigger, Explosion) (0) | 2023.03.13 |
[UE] Character Animation, Collsion (0) | 2023.03.08 |
[UE] Character, GameMode (0) | 2023.03.07 |
[UE] Log 출력하기, Draw Debug 구현 (0) | 2023.03.03 |
댓글
이 글 공유하기
다른 글
-
[UE] Collision(Override), BP와 C++ 실행순서
[UE] Collision(Override), BP와 C++ 실행순서
2023.03.14 -
[UE] Collsion(trigger, MultiTrigger, Explosion)
[UE] Collsion(trigger, MultiTrigger, Explosion)
2023.03.13 -
[UE] Character Animation, Collsion
[UE] Character Animation, Collsion
2023.03.08 -
[UE] Character, GameMode
[UE] Character, GameMode
2023.03.07