본문 바로가기
언리얼엔진 개발/Developing

[UnrealEngine5]TPS 제작 환경에서의 LineTrace 사용하는 법

by yeni_0224 2023. 7. 20.
728x90
반응형

이전에도 LineTrace에 대해 다룬 적이 있었지만, 그 게시물은 VR환경에서의 LineTrace 사용 법이었다.

2023.03.13 - [언리얼엔진 개발/Developing] - [UnrealEngine5]LineTrace로 충돌 감지하기

 

[UnrealEngine5]LineTrace로 충돌 감지하기

드디어 언리얼엔진 개발에 대한 게시물을 올리기 시작한다. 정말 많이 사용하는 LineTrace에 대한 것부터 작성하기로 했다. 총을 발사했을 때 물체와 충돌이 되는지 확인하기 위해 Linetrace를 사용

yeni-0224.tistory.com

같은 Linetrace함수를 사용하고, 원리는 비슷하지만 언리얼엔진 개발 초심자들이 계시다면 이 글이 도움이 되면 좋겠다!

나도 초심자니까아!

 

01  Linetrace Blueprint 사용법

출발점, 끝점을 설정해서 linetrace 노드와 연결해주면 된다

끝점 구하는 방법!

마우스 왼쪽 버튼을 눌렀을 때 linetrace가 실행되도

일정 거리 떨어져있는 위치를표현하기 위해 float 값을 곱해줄 것인데, Get World Location에서 거리 값을 곱해줄 수가 없기 때문에 float 값을 곱해줄 것이라 변환을 해줄 것이다. 그런데 이렇게 곱한 값은 값일 뿐 어느 위치를 가리키는 것이라고 말하기 어렵기 때문에 현재 카메라의 위치 값을 더해주는 것이다.

 

여러개의 결과 값을 도출할 것이라면 Multi Line Trace by Channel

한개의 결과 값을 도출할 것이라면 Single Line Trace by Channel

나는 Single Line Trace by Channel을 사용할 것이다.

 

Linetrace를 쏜 거리 안에 어떤 물체가 검출되었을 때 그 위치에 불꽃 효과가 발생하도록 할 것이다. Spawn Emitter at Location 노드를 사용할 것이다. (Actor이 튀어나오게도 할 수 있다. 그렇다면 Spawn Actor of class)그렇다면 부딪힌 결과 값을 알고 있어야한다. Emitter Template에서 사용할 효과를 할당해주면 된다.

왼쪽 마우스 버튼을 클릭해 linetrace가 실행된 것이 true 라면 spawn emitter 함수가 실행되도록 한다는 것이다. Branch는 true, false의 조건을 쓸 때 사용한다. 이후에 Linetrace 끝점에 도달했을 때 충격을 가해 힘에 의해 물체가 밀리는듯한 현상을 사용하고자 한다면 Add force 함수를 사용하는 방법도 있다.

 

02  LineTrace C++

블루프린트로 구현한 내용을 C++로 옮겨보자.

2023.03.13 - [언리얼엔진 개발/Developing] - [UnrealEngine5]LineTrace로 충돌 감지하기

 

[UnrealEngine5]LineTrace로 충돌 감지하기

드디어 언리얼엔진 개발에 대한 게시물을 올리기 시작한다. 정말 많이 사용하는 LineTrace에 대한 것부터 작성하기로 했다. 총을 발사했을 때 물체와 충돌이 되는지 확인하기 위해 Linetrace를 사용

yeni-0224.tistory.com

*여기서 작성한 Fire 함수에 이어서 작성합니다

먼저 effect를 담아둘 변수를 하나 만들어줄 것이다.

	UPROPERTY(EditDefaultsOnly)
	class UParticleSystem* fireEffect;

particle 변수를 하나 만들어준다. SpawnEmitterAtLocation함수에 넣어줄 변수인 것이다.

//이전 fire 구현 내용에 이어서 계속..
FHitResult hitInfo;
FVector startP = FollowCamera->GetComponentLocation();
FVector endP = startP + FollowCamera->GetForwardVector() * 100000;
FCollisionQueryParams params;
params.AddIgnoredActor(this);

bool bHit = GetWorld()->LineTraceSingleByChannel(hitInfo, startP, endP, ECollisionChannel::ECC_Visibility, params);

if(bHit)
{
    FTransform trans(hitInfo.ImpactPoint);
    UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), fireEffect, trans);
}

그런데 만약 물체와 부딪혔을 때 밀려나는 물리작용이 발생하는 듯한 효과를 구현하고 싶다면

AddForce함수를 사용해주는 것이다.

auto hitComp = hitInfo.GetComponent();
if(hitComp && hitComp->IsSimulatingPhysics()) //물체가 물리작용한다면
{
    //힘이 작용하는 방향
    FVector forDir = (hitInfo.TraceEnd - hitInfo.TraceStart).GetSafeNormal();
    //작용하는 힘의 크기
    FVector force = forDir * 100000 * hitComp->GetMass();
    hitComp->AddForce(force);
}

Get Safe Normal에 대한 정보는

https://docs.unrealengine.com/4.27/en-US/API/Runtime/Core/Math/FVector/GetSafeNormal/

 

FVector::GetSafeNormal

Gets a normalized copy of the vector, checking it is safe to do so based on the length.

docs.unrealengine.com

Normalize와 Get Safe Normal의 차이

1) Normalize

원본의 벡터길이를 1로 바꿔버린다. 수식 자체에 Normalize를 적용할 수 없다.

2) Get Safe Normal

원본은 놔두고 사본을 생성하고, 사본의 값을 1로 바꾸는 것이다. 원본 값을 보존할 수 있고, 괄호 안에 남아있는 값을 normalize 하는 것이다.

728x90
반응형