[UE] Line Trace, Multi Trace, TPS 기본 세팅
목차
Line Trace
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 C05_MultiTrigger.h .cpp C05_FallingBox.h .cpp C05_SpotLight.h .cpp C06_EventTrigger.h .cpp C06_Explosion.h .cpp C07_Override.h .cpp |
|
04_Trace | |
C01_Trigger.h .cpp C01_SphereTrace.h .cpp C02_Cylinder.h .cpp C02_LineTrace.h .cpp C03_MultiTrace.h .cpp |
|
Utilities | |
CHelpers.h | |
CAnimInstance.h .cpp CGameMode.h .cpp CPlayer.h .cpp |
Actor 안에 Camera가 있으면 조정가능?
Trace
Line vs. Sweep
Line
Sweep
- 충돌체의 모양 정의: Box, Sphere, Capsule
Multi일 때 Channel, Objects 차이가 생긴다 (Line과 Sweep 둘 다 해당).
- Object는 블락(Block)만 체크한다.
- Chanel은 첫번째 블락(Block)까지 체크한다. ex. 유리창 깨트리고 벽에 박힌다.
Line Trace
C02_LineTrace.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C02_LineTrace.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FLineTraceResult, class AActor*, InActor, FLinearColor, InColor);
UCLASS()
class U2212_03_API AC02_LineTrace : public AActor
{
GENERATED_BODY()
public:
AC02_LineTrace();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
private:
UFUNCTION()
void StartLaunch(class AActor* InActor, FLinearColor InColor);//Dynamic은 매개변수 이름이 똑같아야 한다.
public:
UPROPERTY(BlueprintAssignable)
FLineTraceResult OnLineTraceResult;
private:
TArray<class AC02_Cylinder*> Cylinders;
};
C02_LineTrace.cpp
더보기
#include "04_Trace/C02_LineTrace.h"
#include "Global.h"
#include "C02_Cylinder.h"
#include "GameFramework/Character.h" //실제적으로 실행시켜주는 역할
AC02_LineTrace::AC02_LineTrace()
{
PrimaryActorTick.bCanEverTick = true;
}
void AC02_LineTrace::BeginPlay()
{
Super::BeginPlay();
CHelpers::FindActors<AC02_Cylinder>(GetWorld(), Cylinders);
//Delegate 사용
OnLineTraceResult.AddDynamic(this, &AC02_LineTrace::StartLaunch);
}
void AC02_LineTrace::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
FVector start = Cylinders[0]->GetActorLocation();
FVector end = Cylinders[1]->GetActorLocation();
//DrawDebugLIne
{
start.Z -= 20;
end.Z -= 20;
DrawDebugLine(GetWorld(), start, end, FColor::Blue);
}
//LineTrace
{
start.Z += 40;
end.Z += 40;
TArray<AActor*> ignores;
ignores.Add(Cylinders[0]);
ignores.Add(Cylinders[1]);
FHitResult hitResult;
UKismetSystemLibrary::LineTraceSingleByProfile(GetWorld(), start, end, "Pawn", false, ignores, EDrawDebugTrace::ForOneFrame, hitResult, true);
if(hitResult.bBlockingHit)
{
if (OnLineTraceResult.IsBound())
OnLineTraceResult.Broadcast(hitResult.GetActor(), FLinearColor::MakeRandomColor());
}
}
}
void AC02_LineTrace::StartLaunch(AActor* InActor, FLinearColor InColor)
{
ACharacter* character = Cast<ACharacter>(InActor); //InActor를 Character로 캐스팅
CheckNull(character);//character==nullptr이면 return
character->LaunchCharacter(FVector(0, 0, 50), true, false);//Launch 오버라이드
}
※ 참고 - LaunchCharcter 함수
더보기
void ACharacter::LaunchCharacter(FVector LaunchVelocity, bool bXYOverride, bool bZOverride)
{
UE_LOG(LogCharacter, Verbose, TEXT("ACharacter::LaunchCharacter '%s' (%f,%f,%f)"), *GetName(), LaunchVelocity.X, LaunchVelocity.Y, LaunchVelocity.Z);
if (CharacterMovement)
{
FVector FinalVel = LaunchVelocity;
const FVector Velocity = GetVelocity();
if (!bXYOverride)
{
FinalVel.X += Velocity.X;
FinalVel.Y += Velocity.Y;
}
if (!bZOverride)
{
FinalVel.Z += Velocity.Z;
}
CharacterMovement->Launch(FinalVel);
OnLaunched(LaunchVelocity, bXYOverride, bZOverride);
}
}
BP_C02_LineTrace
UPROPERTY(BlueprintAssignable)
FLineTraceResult OnLineTraceResult;
UPROPERTY(BlueprintAssignable)는 Event Dispatcher를 만든다.
https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/Blueprints/TechnicalGuide/ExtendingBlueprints/
실행화면
- DrawDebugLine 선과 Capsule이 충돌하여 Launch가 발동한다.
- 충돌 시 BP에서 만든 ChangePlayerColor가 실행되어 Player의 색이 바뀐다.
MultiTrace
중요!!) Channel Trace와 Object Trace의 차이
Channel은 첫 번째 블락까지 겹친 애들 다 체크한다.
Object는 오브젝트 무시하고 블락(Block)만 체크한다.
예시 상황) 총알이 날라와 유리창을 깨고 방 안의 벽에 박혔다.
- Overlap - 유리창이 깨지는 효과를 구현할 수 있다.
- Block - 총알이 벽에 박히는 것을 구현할 수 있다.
LineTraceMulti vs. LineTraceMultiForObjects
//Channel
UKismetSystemLibrary::LineTraceMulti(GetWorld(), start1, end1, ETraceTypeQuery::TraceTypeQuery1, false, ignores, EDrawDebugTrace::ForOneFrame, hitResults1, true);
//Object
UKismetSystemLibrary::LineTraceMultiForObjects(GetWorld(), start2, end2, types, false, ignores, EDrawDebugTrace::ForOneFrame, hitResults2, true);
벽 배치
Multi Trace
C03_MultiTrace.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "C03_MultiTrace.generated.h"
UCLASS()
class U2212_03_API AC03_MultiTrace : public AActor
{
GENERATED_BODY()
private:
UPROPERTY(VisibleAnywhere)
class USceneComponent* Root;
UPROPERTY(VisibleAnywhere)
class UTextRenderComponent* Text;
public:
AC03_MultiTrace();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
private:
float TotalTime;
};
C03_MultiTrace.cpp
더보기
#include "04_Trace/C03_MultiTrace.h"
#include "Global.h"
#include "Components/TextRenderComponent.h"
AC03_MultiTrace::AC03_MultiTrace()
{
PrimaryActorTick.bCanEverTick = true;
CHelpers::CreateComponent<USceneComponent>(this, &Root, "Root");
CreateTextRender();
}
void AC03_MultiTrace::BeginPlay()
{
Super::BeginPlay();
}
void AC03_MultiTrace::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
FVector start = GetActorLocation();
FVector start1 = FVector(start.X + 50, start.Y, start.Z);
FVector start2 = FVector(start.X - 50, start.Y, start.Z);
FVector end1 = start1 + GetActorForwardVector() * 600;
FVector end2 = start2 + GetActorForwardVector() * 600;
TArray<AActor*> ignores;
//Multi로 쏘니 hitResult가 여러개여서 배열로 만들어준다.
TArray<FHitResult> hitResults1;
TArray<FHitResult> hitResults2;
//Channel
UKismetSystemLibrary::LineTraceMulti(GetWorld(), start1, end1, ETraceTypeQuery::TraceTypeQuery1, false, ignores, EDrawDebugTrace::ForOneFrame, hitResults1, true);
//Objects
TArray<TEnumAsByte<EObjectTypeQuery>> types;
types.Add(EObjectTypeQuery::ObjectTypeQuery1);
UKismetSystemLibrary::LineTraceMultiForObjects(GetWorld(), start2, end2, types, false, ignores, EDrawDebugTrace::ForOneFrame, hitResults2, true);
TotalTime += DeltaTime;
if(TotalTime >= 2.0f)
{
TotalTime = 0.0f;
CLog::Log(FString::Printf(L"-- Channel : %d", hitResults1.Num()));
for (const FHitResult& hitResult : hitResults1)
{
FString str = FString::Printf(L"Block : %d, %s", hitResult.bBlockingHit, *hitResult.GetActor()->GetName());
CLog::Log(str);
}
CLog::Log(FString::Printf(L"-- Objects : %d", hitResults2.Num()));
for (const FHitResult& hitResult : hitResults2)
CLog::Log(hitResult.GetActor()->GetName());
}
}
실행화면
- Channel의 경우 맨 앞의 Overlap을 체크하고 뒤에 있는 Block을 연산한다. 하지만 그 뒤의 Block들은 연산하지 않는다.
- 반면에 Object의 경우 맨 앞의 Overlap을 통과하고 뒤에 있는 Block은 모두 연산한다.
TPS 기본세팅
Characters | |
CAnimInstance.h .cpp CPlayer.h .cpp |
|
Utilities | |
CHelpers.h CLog.h .cpp |
|
CGameMode.h .cpp Global.h |
프로젝트 세팅
U2212_04.Build.cs
using UnrealBuildTool;
public class U2212_04 : ModuleRules
{
public U2212_04(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicIncludePaths.Add(ModuleDirectory); //경로찾기!!
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
PrivateDependencyModuleNames.AddRange(new string[] { });
}
}
PublicIncludePaths.Add(ModuleDirectory); 추가
- 경로를 찾는데 필요한 코드이다.
'⭐ Unreal Engine > UE FPS TPS' 카테고리의 다른 글
[UE] TPS Weapon, AnimNotify, Aim (0) | 2023.03.17 |
---|---|
[UE] TPS Weapon - Weapon Framework 짜기 (0) | 2023.03.16 |
[UE] Collision(Override), BP와 C++ 실행순서 (0) | 2023.03.14 |
[UE] Collsion(trigger, MultiTrigger, Explosion) (0) | 2023.03.13 |
[UE] Collision(Overlap, hit) (0) | 2023.03.09 |
댓글
이 글 공유하기
다른 글
-
[UE] TPS Weapon, AnimNotify, Aim
[UE] TPS Weapon, AnimNotify, Aim
2023.03.17 -
[UE] TPS Weapon - Weapon Framework 짜기
[UE] TPS Weapon - Weapon Framework 짜기
2023.03.16 -
[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