언리얼 5

231018 물리 엔진 (사운드 재생) / 레벨 스트리밍

슬뷔 2023. 10. 18. 11:07

지형에 따른 사운드

 

물리재질 : 물리적인 반응을 어떻게 할 것인지 ? 재질

Trace 활용

https://tech-interview.tistory.com/m/269

 

[Unreal] 물리 엔진

1. 물리 엔진 게임 객체를 움직이는 방법에는 매 프레임의 좌표를 변경하는 방법, 컴포넌트를 사용하는 방법, 시퀀서를 사용하는 방법, 물리 엔진을 사용하는 방법 등 여러 방법이 존재한다. 1)

tech-interview.tistory.com

엔진에서의 물리재질은 사운드를 멤버변수로 가지고 있지 않다

 

C++ 클래스제작

PysicalMaterial 상속받아서 PysicalMaterial_Landscape 생성

#include "../Header/global.h"

#include "CoreMinimal.h"
#include "PhysicalMaterials/PhysicalMaterial.h"
#include "PhysicalMaterial_Landscape.generated.h"

UCLASS()
class UNREAL_3TH_API UPhysicalMaterial_Landscape : public UPhysicalMaterial
{
	GENERATED_BODY()

private:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
	USoundBase*			m_Sound;

	// 발위치에 뿌려줄 파티클
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
	UParticleSystem*	m_Particle;

	// 발위치에 뿌려줄 나이아가라 시스템
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
	UNiagaraSystem*		m_Niagara;

public:
	void SetSound(USoundBase* _Sound) { m_Sound = _Sound; }
	void SetParticle(UParticleSystem* _Particle) { m_Particle = _Particle; }
	void SetNiagara(UNiagaraSystem* _Niagara) { m_Niagara = _Niagara; }

	USoundBase* GetSound() { return m_Sound; }
	UParticleSystem* GetParticle() { return m_Particle; }
	UNiagaraSystem* GetNiagara() { return m_Niagara; }
};

Landscape -> LayerInfo 에서 오른쪽마우스 -> 피직스 -> 피지컬머테리얼

PNT_Ground, PNT_Grass 생성

 

Grass_01 LyaerInfo, Ground_01 LayerInfo 에서 피직스 머티리얼 선택

 

플레이어 애니메이션 중 Walk_Fwd 에 노티파이 추가

1. LeftStep

2. RightStep

 

C++ 클래스 중 AnimInstance_Base 에 PlayPhysicalBasedSound, AnimNotify 추가

UCLASS()
class UNREAL_3TH_API UAnimInstance_Base : public UAnimInstance
{
	GENERATED_BODY()
    
private:
	void PlayPhysicalBasedSound(const FString& _strSockName);
    
public:
	UFUNCTION()
	void AnimNotify_LeftStep();

	UFUNCTION()
	void AnimNotify_RightStep();
}

 

프로젝트 세팅 -> Preset ->새 프로파일 생성

콜리전 켜짐 -> Collision Enabled 로 설정

새 트레이스 채널 추가 ( LandScape 만 반응 )

랜드스케이프 피직스 -> 콜리전 프리셋 -> LandScape 로 변경

C++ 클래스 AnimInstance_Base.cpp 

void UAnimInstance_Base::AnimNotify_LeftStep()
{
	LOG(Player, Warning, TEXT("Left Step"));

	PlayPhysicalBasedSound(TEXT("Foot_L"));
}

void UAnimInstance_Base::AnimNotify_RightStep()
{
	LOG(Player, Warning, TEXT("Right Step"));

	PlayPhysicalBasedSound(TEXT("Foot_R"));
}

void UAnimInstance_Base::PlayPhysicalBasedSound(const FString& _strSockName)
{
	// 소유 플레이어 알아내기
	ACharacter_Base* pPlayer = Cast<ACharacter_Base>(TryGetPawnOwner());
	if (!IsValid(pPlayer))
		return;

	// 발 위치 소켓의 시작지점과, 땅을 뚫고 내려간 위치, Trace 끝 지점
	FVector vSockStartPos = pPlayer->GetMesh()->GetSocketLocation(*_strSockName);
	FVector vSockEndPos = vSockStartPos + FVector(0.f, 0.f, -100.f);

	// 충돌 결과를 받을 Result 구조체
	FHitResult hitresult = {};

	// 충돌 옵션 설정 Parameter 구조체
	FCollisionQueryParams param = {};
	param.bReturnPhysicalMaterial = true;	// Trace 충돌 성공 시, 해당 물체의 물리재질 받아오기 옵션
	param.AddIgnoredActor(pPlayer);			// Trace 무시할 액터 등록

	// LineTrace 진행, ECC_GameTraceChannel6 는 Trace_Landscae 채널
	bool bHit = GetWorld()->LineTraceSingleByChannel(hitresult, vSockStartPos, vSockEndPos, ECC_GameTraceChannel6, param);

	if (bHit)
	{
		// 충돌 결과 물리재질을 UPhysicalMaterial_Landscape 로 캐스팅
		UPhysicalMaterial_Landscape* pPMT = Cast<UPhysicalMaterial_Landscape>(hitresult.PhysMaterial);
		if (!IsValid(pPMT))
			return;

		//pPMT->GetParticle();
		//pPMT->GetNiagara();

		USoundBase* pSound = pPMT->GetSound();
		if (IsValid(pSound))
		{
			// hitresult.ImpactPoint;
			UGameplayStatics::PlaySoundAtLocation(GetWorld(), pSound, vSockStartPos);
		}
	}
}

레벨 스트리밍

스트리밍 레벨(Streaming Level)이란 퍼시스턴트 레벨(기본 레벨)의 자식 레벨을 의미한다.

 

https://docs.unrealengine.com/4.27/ko/BuildingWorlds/LevelStreaming/

 

레벨 스트리밍

메모리 사용량을 줄이고 심리스, 로딩화면 없는 월드를 만들기 위해 플레이 도중 레벨을 비동기 로드/언로드하는 기법입니다.

docs.unrealengine.com

 

창 -> 레벨 -> 레벨 클릭 -> 새로 생성 -> Landscape_Sub_01 생성

다른 레벨로 이동할 액터 선택 -> Landscape_Sub_01 -> 우클릭 -> 선택된 액터를 레벨로 이동

 

표시 -> 고급 -> 레벨컬러 (레벨에 따라서 색이 다른걸 눈으로 확인할 수 있다)

레벨 디테일창을 켠다

스트리밍 볼륨 -> + 클릭 -> LevelStreamingVolume 선택

 

LevelStreamingVolume 에 다가가면 큐브 액터가 나타나게 되고, 범위를 벗어나면 사라진다.

단점 

1. LevelStreamingVolume  판정 조건 -> 메인 카메라의 진입조건 기준


랜드스케이프 특정 영역도 레벨로 이동이 가능하다

랜드스케이프 모드 -> 이동

 


보완을 위해 Unload, Load 박스 제작

 

블루프린트 -> 열거형 -> Streaming Type 생성 -> 이너머레이터 추가 -> Load Level / UnloadLevel 추가

 

BPC_LevelStreamingTrigger 생성

BoxCollision 추가

변수 추가 StreamingType / LevelName -> 눈 켜주기!

밖으로 나와서 디테일 셋팅하기

BPC_LevelStreamingTrigger -> 이벤트 그래프 -> ActorBeginOverlap 추가