워터 시스템 (Water System)

타입·2024년 5월 9일
0

언리얼 엔진 공부

목록 보기
3/5
post-thumbnail

워터 시스템

랜드스케이프에 바다, 호수, 강과 같은 을 배치할 수 있는 기능

랜드스케이프 (Landscape)

간단하게 말해서 지형을 의미함

플러그인 활성화

워터 시스템을 사용하기 위해 '편집-플러그인'에서 아래 Water 플러그인을 체크 후 에디터 재실행

콘텐츠 브라우저에서 엔진 콘텐츠 표시, 플러그인 콘텐츠 표시를 체크하면

활성화한 Water 플러그인에 포함된 Water 콘텐츠를 볼 수 있음

참고로 Water Extras엔 WaterTestMap이란 예제맵도 존재

워터 바디 액터 (Water Body Actor)

워터 바디
즉, 물의 본체를 의미하는 액터
워터 메시 액터 (Water Mesh Actor)에 의해 워터 메시 타일로 구성됨

랜드스케이프의 '레이어 편집 활성화'를 체크해주어야 워터 바디 액터를 배치하였을때 랜드스케이프가 워터 바디 액터의 스플라인에 맞게 수정됨

스플라인 (Spline)

점과 점을 잇는 곡선, 워터 바디 액터는 이 스플라인에 따라 물이 채워짐

  • 스플라인에 따라 랜드스케이프에 강이 만들어진 모습

랜드스케이프는 Movility가 Static이므로 인게임 중 스플라인이 변경된다 하더라도 동적으로 지형이 변하지 않는다.

워터 바디 타입

대표적으로 바다, 호수, 강 타입이 존재
(커스텀과 섬 타입도 존재하지만 생략)

바다 워터 바디 (Ocean Water Body)

지평선 끝까지 뻗어나가는 (것처럼 보이는) 수평의 물
실제론 Ocean Water Body의 Ocean Extents에 설정한 범위 만큼 물이 채워짐
Water Zone의 Zone Extent의 범위에 겹쳐야 워터 메시가 그려짐
스플라인 포인트는 같은 높이로 배치됨

Water Zone의 Far Distance Material이 없다면 Water Zone의 Zone Extent 범위를 벗어나는 거리는 물이 보이지 않음

호수 워터 바디 (Lake Water Body)

스플라인 안의 랜드스케이프를 파내어 차오르는 물
바다와 같이 스플라인 포인트는 같은 높이로 배치됨

특징으로 호수 워터 바디의 위치를 높이면 랜드스케이프도 따라서 올라옴

강 워터 바디 (River Water Body)

시작 점부터 끝 점까지 스플라인을 따라 흐르는 물
스플라인 포인트는 다른 높이로 배치 가능

강은 다른 워터 바디를 연결할 수 있는 특징이 있음
(강과 강끼리도 당연히 연결 가능)

워터 바디와의 연결은 렌더링 카테고리의 트랜지션 머티리얼을 사용하여 자동으로 블렌딩

  • Terrain 카테고리에서 Channel Depth를 설정하여 바다와 호수의 깊이를 설정 가능
  • 강의 경우 각 스플라인 포인트에서 설정 가능

수중 포스트 프로세싱 (Underwater Post Processing)

카메라가 물 속에 들어갔을 때 포스트 프로세싱 처리
(불필요한 경우 비활성화)

워터 바디 제외 볼륨

워터 바디에 빈 공간을 만드는 볼륨
해당 공간을 물 밖의 공간으로 여겨 부력 컴포넌트의 동작이나 수중 포스트 프로세싱이 되지 않음

부력 컴포넌트 (Buoyancy Component)

부교(Pontoon)를 이용하여 오브젝트가 수면과 상호작용하여 물에 띄울 수 있음

컴포넌트 설정

  • Static Mesh
    피직스에서 'Simulate Physics'를 활성화하고 'Mass(kg)'도 적절하게 설정
  • Buoyancy Component
    Buoyancy Data에서 Pontoons를 배치하여 메시를 수면에 띄우게 함
    참고로 블루프린트 뷰포트에선 배치한 부교가 보이지 않는데, 메시의 소켓을 이용할 수도 있음
    • Buoyancy Coefficient를 설정하여 부력의 강도 조절 가능

부력 컴포넌트가 제대로 작동하려면 Static Mesh가 반드시 루트 컴포넌트여야 함

  • BuoyancyComponent.h
  • UBuoyancyComponent::BeginPlay()
  • UBuoyancyComponent::Update(DeltaTime)
    해당 함수는 TickComponent(DeltaTime)에서 호출해서 매프레임 불려짐

ApplyForces() 함수에서 컴포넌트의 IsSimulatingPhysics() 함수로 피직스 시뮬레이션 여부를 검사하고 부력 최종 전달

부력 디버깅

  • 콘솔 명령어

    	r.Water.DebugBuoyancy 1

입력 시 Buoyancy Component에서 세팅한 부교가 빨갛게 그려지고 수면과 상호작용하는 모습을 보여줌

액터가 물에 닿아 부력이 전달되는 과정

  • 액터가 워터 바디에 닿음

    • AWaterBody::NotifyActorBeginOverlap()
    • UBuoyancyComponent::EnteredWaterBody()
  • 매 프레임 힘을 가해줌

    • UBuoyancyComponent::ApplyForces()
    • UBuoyancyComponent::ApplyBuoyancy()
// Pontoon의 LocalForce를 정의하는 부분
void UBuoyancyComponent::ComputeBuoyancy(FSphericalPontoon& Pontoon, float ForwardSpeedKmh)
{
	// UBuoyancyComponent::UpdatePontoons()에서 호출됨
	...
    
	float BuoyancyCoefficientWithRamp = BuoyancyData.BuoyancyCoefficient * (1 + BuoyancyRamp);
	const float BuoyantForce = FMath::Clamp(ComputeBuoyantForce(Pontoon.CenterLocation, Pontoon.Radius, BuoyancyCoefficientWithRamp, Pontoon.WaterHeight), 0.f, BuoyancyData.MaxBuoyantForce);
	Pontoon.LocalForce = FVector::UpVector * BuoyantForce * Pontoon.PontoonCoefficient;
}

디버그 명령어

Stat Water

WaterBody_ComputeWaterInfo: 엔진 전체에서 워터 관련 정보를 계산하는 데 사용되는 함수의 비용, 프레임 시간 체크에 유용

다른 영향을 줄만한 액터가 없는 상태에서 Buoyancy Component의 Pontoons 수만큼 비례해서 콜카운트가 증가
Pontoons 4개 x 오브젝트 100개 = 400회 (약 1ms)

Stat WaterMesh

Vertices Drawn: 현재 뷰의 모든 워터 바디에 대해 그려진 버텍스 수
Tiles Drawn: 현재 워터 메시에 표시되는 타일의 총 수

r.Water.WaterMesh.ShowTileBounds 1

명령어로 타일을 볼 수 있음

수면 메시는 LOD를 지원하여 먼 거리에선 더 적은 수의 버텍스를 가지도록 구현 가능

워터 웨이브 에셋 (Water Waves Asset)

워터 바디 액터의 표면에 일어나는 파도를 시뮬레이션함
부력 컴포넌트에 세팅한 부교는 실제 파도의 높이에 따라 반응함

워터 바디의 Wave 카테고리에서 세팅
(강 워터 바디는 스플라인을 따라 별도의 물 흐름이 있어 워터 웨이브 에셋 세팅이 불가)

거스너 워터 웨이브 프로퍼티 (Gerstner Water Waves Properties)

언리얼에서 제공하는 워터 웨이브 에셋

  • Num Waves (파도 수)

  • Wavelenghts (파장)

  • Amplitude (진폭)

워터 시스템은 리플리케이션 되지 않아 멀티플레이 게임에서 사용할 때 주의!

profile
주니어 언리얼 프로그래머

1개의 댓글

comment-user-thumbnail
2024년 5월 9일

https://www.unrealengine.com/marketplace/ko/product/fluid-flux
실시간으로 물이 생성되며 유체가 흐르는 시뮬레이션을 해야한다면 위 에셋을 구매하면 좋습니다.
워터 시스템을 이용하지 않고 나이아가라 플루이드를 이용했다고 하네요.

답글 달기