Scene Component & Collision

Jihyun·2023년 12월 19일
0

Unreal

목록 보기
7/11
post-custom-banner

일인칭 카메라 컴포넌트에 씬 컴포넌트 어태치하기

일인칭 카메라를 움직일 때 카메라를 따라 움직이는 컴포넌트 생성한다

  1. 카메라와 같은 방향을 가리키는 컴포넌트 생성
    -> 컴포넌트를 일인칭 카메라에 어태치해서 컴포넌트가 일인칭 카메라를 따라 자동으로 회전, 컴포넌트의 전방 벡터가 카메라의 전방 방향을 가리키도록 설정
  2. 어떤 물체를 잡을지 판단하고 잡은 물체를 확보해서 플레이어가 움직일 때 플레이어를 따라 움직이는 컴포넌트

씬 컴포넌트

Scene Component : 액터 컴포넌트의 하위 클래스이며, 트랜스폼(위치, 회전 및 스케일)을 가지는 컴포넌트
다른 요소들에 어태치되어 해당 요소의 위치와 회전을 정의하는데 주로 사용된다.

로그에 회전값 출력하기

  1. C++ Scene Component 생성(Grabber)
  2. Player 블루프린트 에디터로 이동하여 Fisrt Person Camera Component를 클릭한 상태에서 C++ Scene Component 추가
  3. 로그에 컴포넌트의 회전 출력하기
    ToCompactString()을 이용하여 액터의 이동, 회전값을 로그에 출력할 수 있다.
    ToCompactString() :FVector, FRotator 값을 FString으로 변환
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	FRotator MyRotation = GetComponentRotation();
	FString RotationString = MyRotation.ToCompactString();
	UE_LOG(LogTemp, Display, TEXT("Grabber Rotation : %s"), *RotationString);
}

Collision

콜리전 반응 레퍼런스
Collision : 물리적 충돌 영역
충돌 가능한 모든 오브젝트는 ObjectType과 일련의 반응들을 통해 다른 오브젝트와 어떻게 상호작용을 할지 결정한다.

Line Trace와 Sphere Sweep

Line Trace : 시작과 끝 방향을 정하여 선을 그었을 때 선과 겹치는 오브젝트와 겹치는 오브젝트를 알려준다.
주로 보이지 않는 광선을 쏴 광선의 진행 방향에 충돌할 물체가 있는지 검사하는 데 사용한다

  • LineTraceSingleBy : 맨 처음 충돌된 객체 반환
  • LineTraceMultiBy : 충돌한 모든 물체를 TArray 형태로 반환

Shape Trace : Line Trace와 유사하나 선이 아닌 특정 도형을 가지고 확인한다.
주로 움직임의 제한을 줄 때 사용한다. 플레이어가 이동 중 벽을 만나면 멈추도록 하거나 할 때를 사용한다.

Trace Channels

[Project Settings] - [Collision]에서 같은 충돌 처리를 하기 위해 충돌 채널을 추가할 수 있다

  • Object Channel : Collision 간의 충돌 처리
  • Trace Channel : Ray Tracing 기능을 이용한 충돌 처리

GetWorld

World : 액터와 컴포넌트에 존재이며 맵 또는 샌드박스를 나타내는 최상위 객체

모든 액터와 컴포넌트에는 GetWorld()가 있다. UWorld 타입 오브젝트를 반환한다.
UWorld 는 게임이 진행되는 환경을 나타낸느 타입 및 클래스이다

#include "Engine/World.h"

//UWorld 타입의 오브젝트를 가져올 때 GetWorld()를 사용한다
//UWorld *World = GetWorld();
//->연산자를 사용하여 오브젝트에서 프로퍼티를 가져올 수 있다
float Time = GetWorld() -> TimeSeconds;
//게임에서 시간이 경과함에 따라 초 단위로 출력
UE_LOG(LogTemp, Display, TEXT("Current Time is : %f"), Time);

DebugDrawLine()을 사용해 라인 트레이스 시각화

DebugDrawLine() : 시작과 끝 벡터 사이에 선을 그려 명확하게 확인할 수 있다.
GetForwardVector() : 현재 컴포넌트의 정면 방향 벡터를 반환한다

#include "DrawDebugHelpers.h"

//Line Trace가 트레이스할 최대 거리. 라인의 끝점이 시작점에서 얼마나 떨어져 있는지를 결정
UPROPERTY(EditAnywhere)
float MaxGrabDistance = 400;

void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
	

	//Grabber 컴포넌트의 위치
	FVector start = GetComponentLocation();
	//Grabber 컴포넌트의 시작 벡터와 forward 벡터를 더한 값 * 라인 트레이스의 최대 거리
    //시작점에서부터 정면 방향으로 MaxGrabDistance만큼 이동한 지점이 끝점
	FVector end = start + GetForwardVector() * MaxGrabDistance;

	DrawDebugLine(GetWorld(), start, end, FColor::Red);
	
}

SweepSingleByChannel()을 이용하여 충돌한 액터 이름 알아내기

SweepSingleByChannel() : GetWorld()에 내장된 함수로 트레이스 채널을 이용하여 물리적 충돌 여부를 알아낸다.
파라미터로는

  • HitResult : 물리적 충돌이 있는 경우 관련 정보를 담은 구조체
  • Start : 탐색을 시작할 위치
  • End : 탐색을 끝낼 위치
  • Rot : 탐색에 사용할 도형의 회전
  • TraceChannel : 물리충돌 감지에 사용할 채널 정보
  • CollisionShape : 탐색에 사용할 기본 도형 정보
  • Params : 탐색 방법에 대한 설정값을 모아둔 구조체
  • ResponseParams : 탐색 반응을 설정하기 위한 구조체
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
	
	//Grabber 컴포넌트의 현재 위치
	FVector Start = GetComponentLocation();
	//Grabber 컴포넌트의 시작 벡터와 forward 벡터를 더한 값 * 라인 트레이스의 최대 거리
	//시작점에서부터 정면 방향으로 MaxGrabDistance만큼 이동한 지점이 끝점
	//GetForwardVector() : 현재 컴포넌트의 정면 방향 벡터를 반환, 해당 컴포넌트가 바라보는 전방 방향
	FVector End = Start + GetForwardVector() * MaxGrabDistance;

	DrawDebugLine(GetWorld(), Start, End, FColor::Red);
	
    FCollisionShape Sphere = FCollisionShape::MakeSphere(GrabRadius);
	FHitResult HitResult;

	//SweepSingleByChannel : bool값을 반환
	//FQuat::Identity : 회전값이 없다
	bool HasHit = GetWorld()->SweepSingleByChannel(HitResult, Start, End, FQuat::Identity, ECC_GameTraceChannel2, Sphere);
	
	//충돌이 있다
	if(HasHit)
	{	
		//HitResult struct을 사용하여 구체 트레이스에 부딪힌 액터를 가져온다
		AActor* HitActor = HitResult.GetActor();
		//GetActorNameOrLabel()을 사용하여 액터의 이름을 가져온다
		UE_LOG(LogTemp, Display, TEXT("Hit actor : %s"), *HitActor->GetActorNameOrLabel());
	}
	else
	{
		UE_LOG(LogTemp, Display, TEXT("No actor hit"));

	}

}

트레이스 채널은 DefaultEngine.ini에서 확인할 수 있다

+DefaultChannelResponses=(Channel=ECC_GameTraceChannel2,DefaultResponse=ECR_Ignore,bTraceType=True,bStaticObject=False,Name="Grabber")

profile
잊어버려도 다시 리마인드 할 수 있도록 공부한 것을 기록합니다
post-custom-banner

0개의 댓글