랜드스케이프에 바다, 호수, 강과 같은 물을 배치할 수 있는 기능
간단하게 말해서 지형을 의미함
워터 시스템을 사용하기 위해 '편집-플러그인'에서 아래 Water 플러그인을 체크 후 에디터 재실행
콘텐츠 브라우저에서 엔진 콘텐츠 표시, 플러그인 콘텐츠 표시를 체크하면
활성화한 Water 플러그인에 포함된 Water 콘텐츠를 볼 수 있음
참고로 Water Extras엔 WaterTestMap이란 예제맵도 존재
워터 바디
즉, 물의 본체를 의미하는 액터
워터 메시 액터 (Water Mesh Actor)에 의해 워터 메시 타일로 구성됨
랜드스케이프의 '레이어 편집 활성화'를 체크해주어야 워터 바디 액터를 배치하였을때 랜드스케이프가 워터 바디 액터의 스플라인에 맞게 수정됨
스플라인 (Spline)
점과 점을 잇는 곡선, 워터 바디 액터는 이 스플라인에 따라 물이 채워짐
- 스플라인에 따라 랜드스케이프에 강이 만들어진 모습
랜드스케이프는 Movility가 Static이므로 인게임 중 스플라인이 변경된다 하더라도 동적으로 지형이 변하지 않는다.
대표적으로 바다, 호수, 강 타입이 존재
(커스텀과 섬 타입도 존재하지만 생략)
지평선 끝까지 뻗어나가는 (것처럼 보이는) 수평의 물
실제론 Ocean Water Body의 Ocean Extents에 설정한 범위 만큼 물이 채워짐
Water Zone의 Zone Extent의 범위에 겹쳐야 워터 메시가 그려짐
스플라인 포인트는 같은 높이로 배치됨
Water Zone의 Far Distance Material이 없다면 Water Zone의 Zone Extent 범위를 벗어나는 거리는 물이 보이지 않음
스플라인 안의 랜드스케이프를 파내어 차오르는 물
바다와 같이 스플라인 포인트는 같은 높이로 배치됨
특징으로 호수 워터 바디의 위치를 높이면 랜드스케이프도 따라서 올라옴
시작 점부터 끝 점까지 스플라인을 따라 흐르는 물
스플라인 포인트는 다른 높이로 배치 가능
강은 다른 워터 바디를 연결할 수 있는 특징이 있음
(강과 강끼리도 당연히 연결 가능)
워터 바디와의 연결은 렌더링 카테고리의 트랜지션 머티리얼을 사용하여 자동으로 블렌딩
- Terrain 카테고리에서 Channel Depth를 설정하여 바다와 호수의 깊이를 설정 가능
- 강의 경우 각 스플라인 포인트에서 설정 가능
카메라가 물 속에 들어갔을 때 포스트 프로세싱 처리
(불필요한 경우 비활성화)
워터 바디에 빈 공간을 만드는 볼륨
해당 공간을 물 밖의 공간으로 여겨 부력 컴포넌트의 동작이나 수중 포스트 프로세싱이 되지 않음
부교(Pontoon)를 이용하여 오브젝트가 수면과 상호작용하여 물에 띄울 수 있음
부력 컴포넌트가 제대로 작동하려면 Static Mesh가 반드시 루트 컴포넌트여야 함
- BuoyancyComponent.h
- UBuoyancyComponent::BeginPlay()
- UBuoyancyComponent::Update(DeltaTime)
해당 함수는 TickComponent(DeltaTime)에서 호출해서 매프레임 불려짐
ApplyForces() 함수에서 컴포넌트의 IsSimulatingPhysics() 함수로 피직스 시뮬레이션 여부를 검사하고 부력 최종 전달
콘솔 명령어
r.Water.DebugBuoyancy 1
입력 시 Buoyancy Component에서 세팅한 부교가 빨갛게 그려지고 수면과 상호작용하는 모습을 보여줌
액터가 워터 바디에 닿음
매 프레임 힘을 가해줌
// 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;
}
WaterBody_ComputeWaterInfo: 엔진 전체에서 워터 관련 정보를 계산하는 데 사용되는 함수의 비용, 프레임 시간 체크에 유용
다른 영향을 줄만한 액터가 없는 상태에서 Buoyancy Component의 Pontoons 수만큼 비례해서 콜카운트가 증가
Pontoons 4개 x 오브젝트 100개 = 400회 (약 1ms)
Vertices Drawn: 현재 뷰의 모든 워터 바디에 대해 그려진 버텍스 수
Tiles Drawn: 현재 워터 메시에 표시되는 타일의 총 수
r.Water.WaterMesh.ShowTileBounds 1
명령어로 타일을 볼 수 있음
수면 메시는 LOD를 지원하여 먼 거리에선 더 적은 수의 버텍스를 가지도록 구현 가능
워터 바디 액터의 표면에 일어나는 파도를 시뮬레이션함
부력 컴포넌트에 세팅한 부교는 실제 파도의 높이에 따라 반응함
워터 바디의 Wave 카테고리에서 세팅
(강 워터 바디는 스플라인을 따라 별도의 물 흐름이 있어 워터 웨이브 에셋 세팅이 불가)
언리얼에서 제공하는 워터 웨이브 에셋
워터 시스템은 리플리케이션 되지 않아 멀티플레이 게임에서 사용할 때 주의!
https://www.unrealengine.com/marketplace/ko/product/fluid-flux
실시간으로 물이 생성되며 유체가 흐르는 시뮬레이션을 해야한다면 위 에셋을 구매하면 좋습니다.
워터 시스템을 이용하지 않고 나이아가라 플루이드를 이용했다고 하네요.