섹터 겹침 처리

지세에 여러 섹터가 있는 경우 섹터가 겹칠 수 있으며, 적어도 섹터 가장자리 주변이 겹치기 쉽습니다. 이러한 겹침은 섹터 하나 또는 모두에서 이동 가능한 영역에 영향을 줄 수 있습니다.

NavData 생성 시스템은 이렇게 겹치는 영역을 식별하고 NavData가 메모리에 로드되는 형상을 올바르게 반영할 수 있도록 해당 영역을 특별하게 처리합니다.

  1. 우선 각 섹터에는 인접 섹터의 형상을 고려하지 않고 자체적으로 생성된 NavData가 있습니다.

    각 섹터는 섹터를 만들 때 사용자가 제공하는 KyGuid 클래스의 인스턴스로 나타내는 전역적으로 고유한 ID로 구성해야 합니다.

  2. 다음으로 모든 인접 섹터 간에 겹치는 영역을 식별합니다. 그런 다음 겹치는 지세 형상의 조합을 반영하는 대체 NavData 청크가 생성됩니다. 이 대체 청크에는 겹치는 모든 섹터에 할당된 고유 ID 조합인 KyGuid로 태그가 지정됩니다.
  3. 대체 청크는 겹치는 섹터 중 어느 한쪽에서 .NavData 파일로 저장됩니다.
  4. 런타임 시 섹터에 대한 NavData가 메모리로 스트리밍되면 Database는 현재 로드된 섹터에 따라 겹침 데이터를 자동으로 교환합니다.

예를 들어 상대적으로 평평한 평지가 있는 섹터와 언덕이 있는 인접 섹터가 있다고 가정합니다. 두 섹터의 형상이 약간 겹치므로 언덕의 일부가 평지 레벨 아래에 돌출되고 평지의 일부가 언덕 아래로 확장됩니다.

평지에 대한 NavData만 로드할 경우 관련 NavData는 평평한 지세를 반영합니다. 언덕만 로드할 경우 관련 NavData는 언덕 사면만 반영합니다. 두 섹터를 동시에 로드할 경우 평지와 언덕의 겹치는 부분이 겹치는 영역을 표현하는 대체 청크로 자동으로 바뀝니다. 이때 봇을 한 섹터에서 다음 섹터로 전달할 수 있습니다.

이 프로세스는 전체적으로 투명하게 처리됩니다. 사용자는 NavData 생성 시스템을 동일하게 실행하면서 다른 모든 섹터를 제공하기만 하면 됩니다. 즉, 겹침 데이터의 생성 및 런타임 연결이 자동으로 처리됩니다.

겹침 데이터 생성 제어

자동 겹침 탐지 및 연결 시스템은 NavMesh가 섹터 사이의 테두리를 따르는 경우에도 현재 게임으로 로드된 섹터 세트의 형상과 언제나 일치하도록 모든 섹터 조합을 원활하게 처리되도록 설계되었습니다.

그러나 일부 시나리오에서는 섹터에 대한 NavData의 메모리 사용량을 줄이도록 겹침 데이터 생성을 막으려고 할 수 있습니다. 일반적으로 NavMesh의 정확성을 손상시키지 않고 겹침 데이터 생성을 비활성화할 수 있는 시나리오가 아래에 설명되어 있습니다.

교환 가능한 섹터 사용

때때로 게임 코스 중에 지세 형상이 크게 변경될 수 있는 경우 해당 섹터에 대한 NavData를 두 가지 다른 상태로 생성하여 런타임 시 지세 상태가 변경될 때 상태를 교환할 수도 있습니다. 교환 가능한 섹터에 대한 일반적인 예는 런타임 시 파괴될 수 있는 대형 건물이 있는 영역입니다. 건물이 제 자리에 있는 동안 캐릭터가 지면에서 건물 주위를 걸어가고 심지어는 캐릭터가 건물 내부나 지붕 위를 이동하게 할 수 있습니다. 하지만 건물이 파괴되면 캐릭터가 전에 건물이 있었던 영역을 통과하여 지면을 따라 자유롭게 움직여야 합니다.

각 상태의 형상에 대해 서로 다른 섹터를 설정하고 사용자의 월드에서 나머지 섹터와 함께 동시에 두 섹터를 생성하면 교환 가능한 이러한 섹터에 대해 NavData를 투명하게 만들 수 있습니다. 예를 들어 건물이 있는 상태의 지세 형상이 포함된 섹터를 하나 만들고 건물이 파괴된 후의 지세 형상이 포함된 다른 섹터를 만듭니다. Generator는 두 버전의 교환 가능한 섹터에 대한 NavData를 투명하게 만들고 두 버전을 주변 섹터에 연결하는 겹침 데이터를 만듭니다.

그러나 기본적으로 NavData 생성 시스템은 두 버전의 교환 가능한 섹터를 동시에 메모리로 스트리밍할 수 있다고 간주합니다. 공간에서 두 섹터가 겹치는 것을 탐지하고 자체적으로 각 섹터에 대해 NavMesh를 만드는 것 외에 형상의 조합을 위해 교환 가능한 섹터의 전체 영역을 덮는 겹침 데이터도 만듭니다. 이는 시스템이 런타임 시 여전히 원활하게 작동한다는 점에서 문제가 아닙니다. 언제든지 어떤 섹터를 로드하든지 항상 지세를 제대로 나타내는 NavMesh가 있습니다. 하지만 두 버전의 교환 가능한 섹터가 동시에 로드되는 경우는 없으므로, 교환 가능한 섹터의 경우 겹침 데이터가 필요 없습니다. 따라서 처음부터 NavData 생성 시스템에서 겹침 데이터를 만들지 못하도록 하여 메모리를 절약할 수 있습니다.

Navigation Lab 사용

Navigation Lab에서 독점 섹터를 설정하려면

  1. Navigation Lab의 장면에 여러 .obj 파일을 추가하여 다중 섹터를 설정합니다.
  2. Scene View 창에서 Add Excl. Sectors를 클릭합니다. "ExclusiveSectors"라는 새 요소가 Scene View의 ExclusiveGuids 트리에 추가됩니다.
  3. 새 "ExclusiveSectors" 요소를 클릭합니다.
  4. 3D 보기의 오른쪽에 있는 Attribute Editor 창을 엽니다. 창에서 장면에 현재 나타나는 모든 섹터를 나열합니다.
  5. 서로에 대해 독점적인 모든 섹터를 선택합니다.

    섹터 상자를 선택할 때마다 Activate 버튼이 나타납니다. 3D 보기에서 해당 섹터만 표시하려면 이 버튼을 클릭합니다(원하는 경우).

    Scene View에서 "ExclusiveSectors" 요소의 이름이 업데이트되어 어떤 섹터를 관리하는지 나타냅니다.

필요에 따라 여러 가지 다른 독점 섹터 세트를 설정할 수 있습니다.

C++에서 Generator 사용

GeneratorInputOutput::AddExclusiveGuids()를 호출할 때 해당 섹터의 KyGuids를 제공하여 동시에 로드되지 않는 섹터를 Generator에게 알려줄 수 있습니다. Generator는 해당 섹터 조합에 대한 겹침 데이터를 생성하지 않습니다. 필요한 만큼 이 메서드를 호출하여 여러 독점 섹터 세트를 설정할 수 있습니다.

고정 단계 또는 그리드 기반 분할 사용

일부 게임 프로젝트는 그 범위가 각 셀에 대해 일관된 길이와 너비를 가진 일반 축에 정렬된 그리드를 따르는 스트리밍 하위 레벨을 사용합니다. 프로젝트가 인접한 하위 레벨 간의 분할을 레이아웃하기 위해 이와 같은 그리드를 사용하는 경우 섹터 범위를 정의하는 셀 상자를 사용하여 불필요한 겹침 데이터 생성을 피할 수 있습니다.

이 방법에서는 NavData 생성 프레임워크에서 내부적으로 사용하는 셀 크기를 그리드 셀 크기에 맞게 정렬합니다. 각 섹터에 대해 해당 섹터에 정렬되는 셀을 정의하는 상자 범위를 제공합니다.

  • 그리드의 각 셀에 대한 NavData는 셀 상자가 해당 셀을 포함하는 섹터에만 저장됩니다.
  • 각 셀에 대한 NavData는 GeneratorInputProducer 클래스가 삼각형을 할당한 섹터에 관계 없이 해당 셀을 교차하는 지세의 모든 삼각형 조합을 반영합니다.
  • 셀 상자를 구성한 겹치는 섹터에 대해서는 어떤 겹침 데이터도 생성되지 않습니다. 특정 섹터 조합에 대해 겹침 데이터를 강제로 사용하도록 해야 하는 경우 GeneratorInputOutput: : AddExplicitOverlapSectors()를 호출하여 그렇게 할 수 있습니다.

각 NavData 셀은 언제나 겹치는 형상 조합을 모두 반영하지만 각 셀은 한 섹터에만 저장되기 때문에, 겹치는 섹터 중 하나의 지세 메시만 게임으로 로드하는 경우 겹침 영역에서 NavData와 형상 사이에 현지화된 불일치가 나타날 수 있습니다.

각 섹터에 대해 사용할 셀 상자 범위를 결정하려면 다음을 수행할 수 있습니다.

  • 값을 계산합니다. 3D 셀 상자의 원점은 언제나 3D 월드 공간과 동일한 원점에 있으므로 셀 상자에 있는 각 셀의 너비와 길이는 GeneratorInputOutput.m_params.m_cellSize의 값에 따라 결정됩니다. 셀 상자는 항상 축에 정렬됩니다.
  • 섹터에 대해 첫 번째 생성 패스를 수행한 다음 Navigation Lab에서 NavData를 열고 섹터에 대해 생성된 NavData에서 셀의 레이아웃을 봅니다.

코드 예는 Tutorial_Generation_cellbox.cpp 파일을 참조하십시오.

Navigation Lab 사용

  • 내부 셀 분할 그리드의 크기를 설정하려면 Generation 패널의 Parameters 그룹에서 Cell size (m) 컨트롤 값을 설정합니다.
  • Scene View 패널에서 차례로 각 섹터를 선택하고 Attribute Editor를 엽니다. Cell box 영역에서 Active 컨트롤을 선택하고 수평 X축 및 Y축을 따라 선택한 섹터의 셀 상자 범위를 설정합니다.

    Generation Inputs 도구 상자에서 CellBoxes 버튼을 토글하여 3D 보기에서 셀 상자의 렌더링을 토글할 수 있습니다.

C++에서 Generator 사용

  • 내부 셀 분할 그리드의 크기를 설정하려면 GeneratorInputOutput.m_params.m_cellSize 클래스 구성원 값을 설정합니다.
  • 각 섹터에 대해 GeneratorSectorConfig::SetInputCellBox()를 호출하여 수평 X 및 Y축을 따라 셀 상자의 범위를 설정합니다.