[ Unreal Engine 5 / #10 Trace Collision ]

SeungWoo·2024년 9월 19일
0

[ Ureal Engine 5 / 수업 ]

목록 보기
11/31
post-thumbnail

  • LineTrace

  • 레이캐스트와 트레이스

    • 게임에서 플레이어 캐릭터가 무언가를 바라보고 있는지 확인하여 그런 경우 게임을 어떤 상태로 변경하고자 (예를 들어 플레이어가 무언가를 바라보면 강조시키고자) 하는 경우가 있습니다.
    • 아니면 적이 플레이어 캐릭터를 볼 수 있는지 확인하여 그런 경우 어떤 식으로든 발사 또는 교전을 시작시켰으면 하는 경우도 있습니다.
    • 이 두 가지 모두 Raycast (레이캐스트) 또는 Trace (트레이스)를 통해 보이지 않는 광선을 "발사"하여 두 점 사이에 걸리는 지오메트리가 있는지 확인하고, 걸리는 지오메트리가 있으면 어떤 작업을 할 수 있도록 걸린 것을 반환합니다.
    • 오브젝트 또는 트레이스 채널로 트레이스를 실행하는 것에 추가로, 트레이스를 실행시켜 Single (싱글) 히트 또는 Multi (멀티) 히트 감지가 가능
  • 블루프린트 LineTrace

  • Line Trace는 특정 지점에서부터 직선 상의 충돌 감지(검사)를 수행하는 기능

  • Line Trace의 주요 사용 사례

    • 전투 시스템: 총알이 발사되는 방향으로 충돌하는 물체 확인.
    • 인터랙션: 플레이어가 상호작용 가능한 오브젝트 확인.
    • 시선 교정: 캐릭터가 바라보고 있는 방향에 있는 물체 탐지.


Collision

콜루젼 필터링 사이트
https://www.unrealengine.com/ko/blog/collision-filtering

구조체


구조체(Structure)

  • 함수 (X) , 상속 (X)
  • 주로 여러 변수를 하나로 묶어 효율적으로 데이터를 처리
  • USTRUCT()
  • 구조체가 특정한 클래스에서만 자주 사용될 것이라면 그 클래스의 헤더 파일 하단에 구조체를 정의하는 편이 좋지만, 범용적으로 여러 곳에서 사용될 구조체라면 사용자가 정의한 헤더에 몰아서 정의하는 편

구조체 예제

USTRUCT(BlueprintType) // 블루프린트에서도 사용가능한 매크로
struct FMyGameStruct   // F를 반드시 붙여야된다 블루프린트 연계시 반드시
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "State")
	int32 Health;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "State")
	int32 Stamina;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "State")
	float strength;

	FMYGameStart()
		:Health(100), Stamina(100), strength(50.0f)
	{}
};

언리얼 엔진 구조체 Document
https://dev.epicgames.com/documentation/en-us/unreal-engine/structs-in-unreal-engine

  • Detail
    • 스마트 포인터 및 가비지 컬렉션 : UStruct는 언리얼 엔진의 메모리 관리 시스템을 활용하여 UObjects의 안전한 관리를 돕습니다.
    • 적용 범위 : 단순한 데이터 관리에는 구조체가 적합하지만, 복잡한 기능이나 상호작용이 필요할 경우 UObject나 AActor를 사용하는 것이 바람직합니다.
    • 복제 지원 : 구조체 자체는 네트워크 복제에 포함되지 않으나, 구조체 내의 UProperty 변수는 복제 대상이 될 수 있습니다.
    • 자동 함수 생성 : UStruct에 BlueprintType 태그를 추가하면 Make 함수가, 적어도 하나의 BlueprintReadOnly 또는 BlueprintReadWrite 속성이 있으면 Break 함수가 자동으로 생성됩니다. 이는 블루프린트에서 구조체를 더 쉽게 다룰 수 있게 해줍니다.

tip

  • 안전한 관리
    • 얕은 복사
      • 얕은 복사는 아주 최소한만 복사를 한다.
      • 값을 복사한다 하더라도, 인스턴스가 메모리에 새로 생성되지 않는다. 값 자체를 복사하는 것이 아니라 주소값을 복사하여 같은 메모리를 가리키기 때문이다.
    • 깊은 복사
      • 데이터 자체를 통째로 복사한다.
      • 복사된 두 객체는 완전히 독립적인 메모리를 차지한다.
      • value type의 객체들은 깊은 복사를 하게 된다.
  • safeptr -> 메모리 누수를 안전하게 방지하는 주소포인터

프로젝트 LineTrace

LineTrace

void ACTPSPlayer::InputInteraction(const FInputActionValue& value)
{
	// 시작점
	FVector _Start = GetActorLocation();
	// 끝점
	FVector _End = _Start + GetActorForwardVector()* 2000.0f;
	// Trace 결과 값 struct = BreakResult
	FHitResult _HitOut;

	FCollisionQueryParams _TraceParams;
	//
	GetWorld()->
    LineTraceSingleByChannel(
    _HitOut,
    _Start,
    _End,
    ECollisionChannel::ECC_Visibility,
    _TraceParams);

	// true : 계속 살아있을껀지
	DrawDebugLine(GetWorld(), _Start, _End, FColor::Green, true, 10.0f);
}

사용 예시 )

  • AddIgnoreActor로 특정 액터를 트레이스 대상에서 제외
    FCollisionQueryParams IgnoreOwner = FCollisionQueryParams::DefaultQueryParam;
    IgnoreOwner.AddIgnoredActor(GetOwner());

  • Multi- LineTraceByChannel
    • Line Trace 와 같으나, 결과 값을 Array 의 복수형태로 반환

void ACTPSPlayer::InputInteraction(const FInputActionValue& value)
{
#pragma region sigle Trace
	/*
	// 시작점
	FVector _Start = GetActorLocation();
	// 끝점
	FVector _End = _Start + GetActorForwardVector()* 2000.0f;
	// Trace 결과 값 struct = BreakResult
	FHitResult _HitOut;

	FCollisionQueryParams _TraceParams;
	//
	GetWorld()->LineTraceSingleByChannel(_HitOut, _Start, _End, ECollisionChannel::ECC_Visibility, _TraceParams);

	// true : 계속 살아있을껀지
	DrawDebugLine(GetWorld(), _Start, _End, FColor::Green, true, 10.0f);
	*/
#pragma endregion

#pragma region Multi Trace
	FVector _Start = GetActorLocation();
	FVector _End = _Start + GetActorForwardVector() * 2000.0f;
	TArray<FHitResult> _HitOut;

	FCollisionQueryParams _TraceParams;

	GetWorld()->LineTraceMultiByChannel(_HitOut, _Start, _End, ECC_GameTraceChannel1, _TraceParams);
	// ECC_GameTraceChannel1-> Collision Profile 셋팅에 직접 만든 첫번째 채널

	//DrawDebugLine(GetWorld(), _Start, _End, FColor::Red, true, 10.0f);
	
	// 맞은 적들을 표시할때
	for (const FHitResult& Hit : _HitOut)
	{
		// 충돌한 지점
		FVector HitLocation = Hit.ImpactPoint;

		// 시작 지점에서 충동한 지점까지 디버그 라인 그리기
		DrawDebugLine(GetWorld(), _Start, _End, FColor::Green, true, 10.0f, 0, 1.f);

		DrawDebugSphere(GetWorld(), HitLocation, 10.0f, 12, FColor::Blue, true, 5.0f);

		_Start = HitLocation;
	}

#pragma endregion
}

업로드중..

profile
This is my study archive

0개의 댓글