🎮Unreal4/C++

[UE4] Sphere Trace (SphereTraceMultiForObjects, meta매크로, TEnumAsByte, AddRadialImpulse)

공대 컴린이 2023. 3. 7. 19:25
728x90

📚 Trace

🌐 Sphere Trace

박스 안에 위치하는 Sphere Trace에 감지된 액터들이 수류탄처럼 폭발하듯 터지는 기능을 구현해보았다.

 

먼저 SphereTrace 함수를 실행시키기 위해 필요한 매개변수들을 초기화해주었다.

 

Trace 함수 UKismetSystemLibrary 클래스에 존재하는데, 자동완성의 종류를 보면 단순 Multi 와, MultiByProfile, MultiForObjects로 총 3가지 종류가 있다. 단순히 Multi라고만 적혀있는 것이 Channel 값을 통해 작동된다.

 

그러나 C++ 클래스의 내부적인 Trace 정의들을 살펴보면 실제로는 Channel과 Objects 두 종류 뿐이다. Profile은 단순히 사용하기 편하도록 Channel Trace를 나눠놓은 것이고, Profile의 함수 정의를 보면 결국 Channel Trace를 호출하여 사용한다. 

 

수류탄 기능을 구현하기 위해서 SphereTraceMultiForObjects 함수를 사용해 볼 것이다.

 

UFUNCTION(BlueprintCallable, Category="Collision", meta=(bIgnoreSelf="true", WorldContext="WorldContextObject", AutoCreateRefTerm="ActorsToIgnore", DisplayName = "MultiSphereTraceForObjects", AdvancedDisplay="TraceColor,TraceHitColor,DrawTime", Keywords="sweep"))
	static bool SphereTraceMultiForObjects(const UObject* WorldContextObject, const FVector Start, const FVector End, float Radius, const TArray<TEnumAsByte<EObjectTypeQuery> > & ObjectTypes, bool bTraceComplex, const TArray<AActor*>& ActorsToIgnore, EDrawDebugTrace::Type DrawDebugType, TArray<FHitResult>& OutHits, bool bIgnoreSelf, FLinearColor TraceColor = FLinearColor::Red, FLinearColor TraceHitColor = FLinearColor::Green, float DrawTime = 5.0f);

 

사용하려는 SphereTraceMultiForObjects 함수의 정의로 들어가서 헤더파일에 선언되어있는 것을 확인해보면 다양한 meta 매크로가 설정되어있는 것을 볼 수 있다.

 

DisplayName블루프린트에서 검색되는 함수명(MultiShpereTraceForObjects)을 알려준다. C++ 클래스의 함수명과 다르게 지정된 이유는, C++클래스에선 재정의가 가능하고 블루프린트에선 재정의가 불가능하도록 하기 위함이다.

 

World Context는 원래 WorldContextObject에 자동으로 들어가있는 World를 매개변수인 const UObject* WorldContextObject에 연결하라는 역할을 수행한다. 이렇게 기본값으로 쓰인 매개변수는 블루프린트에서 나타나지 않는다. 따라서 블루프린트의 MultiShpereTraceForObjects 함수에서는 World 값이 보이지 않는다.

 

AdvancedDisplay 매크로로 묶여있는 것들은 블루프린트에 접혀있는 속성들이다.

 

Keyword는 블루프린트에서 검색할 때 해당 키워드를 검색하면 키워드로 묶인 함수가 전부 나타나게 된다. 태그와 비슷한 기능이다.

 

함수의 기본값은 meta 데이터로 지정할수도 있고, 매개변수의 디폴트 매개변수로 지정할수도 있다.

이러한 meta 매크로, 태그들을 확인하고싶다면 언리얼 엔진 문서의 UFunction 문서를 확인하면 된다.

 

SphereTrace 의 함수에 대해 조금 알아봤으니 실제로 사용해보도록 하자.

 

SphereTraceMultiForObjects 함수의 매개변수가 매우 많으므로 하나씩 확인해보자.

💡 SphereTraceMultiForObjects 

  • const UObject* WorldContextObject : World를 전달
  • const FVector Start : Trace 시작 위치
  • const FVector End : Trace 끝 위치
  • float Radius : Shpere 범위의 반지름
  • const TArray<TEnumAsByte<EObjectTypeQuery> > & ObjectTypes : 추적할 오브젝트 타입 배열
    • TEnumAsByte
      - EObjectTypeQuery는 사이즈가 없는 Enum값이기 때문에 사이즈를 지정하기 위해 TEnumAsByte를 사용한다.
      - 직렬화를 할 때는 무조건 사이즈가 정의되어야 하기 때문에 Enum값을 매개변수로 전달하기 위해 사용한다.
    • EObjectTypeQuery
      - EObjectTypeQuery의 1,2,3,4 ...는 콜리전 프리셋에 오브젝트 반응으로 있는 Type들의 순서를 의미한다.

  • bool bTraceComplex : 복잡한 충돌체를 체크할 것인지
  • const TArray<AActor*>& ActorsToIgnore : 추적하지 않을 대상들 배열
  • EDrawDebugTrace::Type DrawDebugType : EDrawDebugTrace 의 Type값 전달
    (None/ForOneFrame/ForDuration/Persistent)
  • TArray<FHitResult>& OutHits : Hit Result 결과를 반환해줄 배열
  • bool bIgnoreSelf : 자기 자신을 제외할 것인지
  • FLinearColor TraceColor : Trace 범위를 그릴 색상
  • FLinearColor TraceHitColor : Hit 된 영역을 그릴 색상
  • float DrawTime : Trace Line들이 그려질 시간

이렇게 구한 SphereTraceMultiForObjects 함수의 결과를 bool 변수로 받아, Hit 되었다면 True를, Hit 된 객체가 없다면 False를 반환받았다.

 

이후 폭발 Particle을 활성화해주었고, 매개변수로부터 반환받은 Hit Result 배열을 사용하였다.

충돌된 Actor의 Root Component를 Static Mesh Component로 형변환하여 받아오고, SimulatingPhysics 가 켜져있는 Mesh에 전부 AddRadialImpulse 해주었다.

 

AddRadial- 함수는 ApplyRadialDamage 함수의 반대역할로 구 형태의 데미지를 주는 함수이다.

AddRadial의 종류로 Impulse와 Force가 있다.

Force 달려와서 때리는 힘을 의미하고 Impulse그걸 받아서 날아가는 힘을 의미한다. 따라서 나는 수류탄과 같이 터지는 기능을 구현하기 위해 AddRadialImpulse 함수를 사용하였다.

💡 AddRadialImpulse 

void UPrimitiveComponent::AddRadialImpulse(FVector Origin, float Radius, float Strength, ERadialImpulseFalloff Falloff, bool bVelChange)
{
	if(bIgnoreRadialImpulse)
	{
		return;
	}

	FBodyInstance* BI = GetBodyInstance();
	if (BI)
	{
		BI->AddRadialImpulseToBody(Origin, Radius, Strength, Falloff, bVelChange);
	}
}

 

  • FVector Origin : 퍼져나갈 위치 벡터
  • float Radius : 퍼져나갈 반경
  • float Strength : 강도 (퍼져나갈 힘)
  • ERadialImpulseFalloff Falloff : Constanct - 힘이 일정하게 퍼짐, Linear - 멀어질수록 줄어듬

이때 매개변수의 강도 값은 질량(Mass)힘(ImpulseAmount)를 곱해 전달해주었다.

질량(Mass)은 Mesh의 GetMess함수로 구할 수 있지만, GetMass 값을 그대로 매개변수로 넣으면 질량이 작을수록 폭발강도도 작아지기 때문에 작은 물체가 더 멀리 날아가야하는 폭발 원리와 반대된다.

따라서 MaxMass를 설정하고 해당 강도에서 GetMass 강도를 빼주어, 작은 물체가 더 멀리 날아가도록 하였다. 거기에 폭발하는 힘 ImpulseAmount 값을 곱해서 매개변수로 전달해주었다.

 

결과적으로 테스트 박스와 충돌 시 Sphere Trace에 감지된 중력을 갖는 Mesh들이 폭발되며 날아가는 모습을 확인할 수 있었다.

 


참조

https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/GameplayArchitecture/Functions/

 

UFunction

게임플레이 클래스용 함수 생성 및 구현 레퍼런스입니다.

docs.unrealengine.com

728x90