그래프를 미리 계산하고 그 데이터를 저장하는 방법

모든 그래프는 파일로 저장하고 불러올 수 있습니다. 실제로 에디터가 항상 하는 작업이기도 하며, Unity 직렬화는 거의 사용되지 않고, 대신 모든 그래프 설정이 직렬화되어 바이트 배열에 저장됩니다. 그러나 설정뿐만 아니라 계산된 후 그래프는 모든 노드를 압축된 바이트 배열 표현으로 저장할 수 있으며, 이를 파일에 저장하고 다른 곳에서 불러올 수 있습니다.
A* 인스펙터의 Save & Load 탭에서 "Save to file"과 "Load from file"이라는 두 개의 버튼을 사용하여 그래프 파일을 저장하고 불러올 수 있습니다.

Caching Graph Calculation

시작할 때 그래프를 다시 계산하는 것이 일반적이지만, 때로는 특히 RecastGraph를 사용하거나 모바일용으로 개발하는 경우 시작 시 지연이 매우 성가실 수 있습니다. 또한 어떤 이유로 시작 시 그래프를 계산할 수 없는 경우도 있습니다.
이 경우 그래프 캐싱이 유용합니다. 에디터에서 그래프를 스캔하고 외부 파일에 저장한 다음 시작 시 로드할 수 있게 합니다. 대부분의 경우 그래프를 스캔하는 것보다 훨씬 빠르며, 그래프가 어떻게 보일지 정확히 알 수 있습니다.

캐시를 생성하려면 A* 인스펙터의 Save & Load 탭을 열고 Generate Cache를 클릭하십시오. 저장하기 전에 그래프를 다시 스캔할지 묻습니다. 이제 저장된 그래프가 시작 시 모든 노드 정보가 그대로 로드되므로 계산 시간이 필요하지 않습니다.



Saving Graphs to File and Loading them

나중에 불러올 수 있도록 그래프를 파일로 저장하고 싶을 수도 있습니다. 예를 들어 서버에서 런타임 중에 불러올 수도 있습니다.

그래프를 저장하려면 Save & Load 탭을 열고 Save to file 버튼을 클릭하십시오. 설정만 포함할지, 설정과 노드 데이터를 포함할지 선택할 수 있습니다. 설정만 포함하는 경우 그래프가 로드된 후 다시 계산해야 캐릭터가 내비게이션에 사용할 수 있습니다. 모든 그래프를 다시 계산하려면 다음을 사용할 수 있습니다:

AstarPath.active.Scan();

그래프를 다시 로드하려면 Load from file 버튼을 누르고 파일을 찾기만 하면 됩니다. 이 작업은 현재 그래프를 대체한다는 점에 유의하세요.

Loading and Saving using Code

런타임 중에 그래프를 로드하거나 저장하려면, 당연히 에디터 인터페이스를 사용할 수 없습니다.

파일을 저장하고 불러오는 쉬운 API가 있습니다. 이 API는 그래프 설정을 바이트 배열로 직렬화합니다. 기본적으로 노드 정보가 포함됩니다(그래프가 먼저 스캔되었다고 가정합니다).

byte[] bytes = AstarPath.active.data.SerializeGraphs();

더 많은 제어를 원한다면 몇 가지 설정을 추가할 수 있습니다.

var settings = new Pathfinding.Serialization.SerializeSettings();

// 설정만 저장
settings.nodes = false;
byte[] bytes = AstarPath.active.data.SerializeGraphs(settings);

저장된 데이터를 로드하려면 다음을 호출할 수 있습니다:

AstarPath.active.data.DeserializeGraphs(bytes);

설정만 로드하는 경우, 설정을 로드한 후 Scan을 호출하고 싶을 수 있습니다:

AstarPath.active.data.DeserializeGraphs(bytes);
AstarPath.active.Scan();

Additive Loading

현재 로드된 그래프를 대체하는 대신, 다음을 사용하여 그래프를 추가적으로 로드할 수 있습니다:

AstarPath.active.data.DeserializeGraphsAdditive(bytes);

다음 방법을 사용하여 그래프를 언로드할 수 있습니다:

var data = AstarPath.active.data;
var myGraph = data.gridGraph;
data.RemoveGraph(myGraph);

Including Data in a TextAsset

그래프 데이터를 텍스트 에셋에 포함하면 빌드에 쉽게 포함할 수 있습니다. 데이터를 파일로 저장한 후 해당 파일의 이름을 "myGraph.bytes"와 같이 변경하고 Unity 프로젝트에 넣으세요. 이렇게 하면 Unity가 해당 파일을 이진 정보로 처리하게 됩니다. 확장자가 .txt와 같은 경우, Unity가 텍스트로 읽으려고 하기 때문에 데이터가 손상될 수 있습니다. 일부 운영 체제는 확장자를 숨기는 것을 좋아하므로, Unity가 .bytes 확장자로 파일을 인식하지 않는다면 실제로 .bytes 확장자를 가지고 있는지 확인하십시오. 확장자가 .zip(또는 다른 확장자)일 경우 단순히 숨겨져 있을 수 있습니다. 그런 다음 변수에 참조하고 .bytes 필드에 접근하여 텍스트 에셋에서 그래프를 로드할 수 있습니다.

using UnityEngine;
using System.Collections;
using Pathfinding;

public class TestLoader : MonoBehaviour {
    public TextAsset graphData;

    // 게임 시작 시 그래프 로드
    void Start () {
        AstarPath.active.data.DeserializeGraphs(graphData.bytes);
    }
}

Internal Data Structure

모든 설정은 JSON으로 직렬화됩니다. 이는 전방 및 후방 호환성을 유지하는 좋은 방법입니다. 아래 언급된 모든 파일은 크기를 줄이고 데이터를 쉽게 처리할 수 있도록 단일 zip 파일로 압축됩니다. 즉, zip 파일을 열어 설정을 수동으로 편집할 수도 있습니다.

 

참고
아래에 언급된 많은 파일은 항상 zip에 포함되지 않습니다. 파일에 관련 정보가 포함되지 않는다고 판단되면(예: 사용자가 만든 연결을 저장하지만 연결이 생성되지 않은 경우) 해당 파일은 제외됩니다.

Meta

모든 직렬화에는 meta.json 파일이 포함됩니다. 이 파일은 특정 그래프와 연결되지 않은 정보나 다른 그래프를 로드하는 데 필요한 정보를 포함합니다.

메타 파일에는 다음 내용이 포함됩니다:

  • 시스템의 버전 번호
  • 저장된 그래프 수
  • 각 그래프를 식별하기 위한 GUID 값
  • 각 그래프의 유형

아래는 meta.json 파일의 예입니다:

{
    "version": "3.0.9.5",
    
    "graphs": 1,
    
    "guids": 
        [
            "0d83c93fc4928934-8362a8662ec4fb9d"
        ],
    
    "typeNames": 
        [
            "Pathfinding.GridGraph"
        ]
}

Graph Settings

각 그래프의 설정은 "graph#.json"으로 저장되며, 여기서 #는 그래프 번호를 나타냅니다. 다음은 그리드 그래프의 직렬화된 설정 예시입니다(길이를 줄이기 위해 일부 설정은 제거되었습니다):

{
   "aspectRatio":1,
   "rotation":{
      "x":0,
      "y":0,
      "z":0
   },
   "center":{
      "x":0,
      "y":-0.1,
      "z":0
   },
   "unclampedSize":{
      "x":100,
      "y":100
   },
   "nodeSize":1,
   "maxClimb":0.4,
   "maxClimbAxis":1,
   "maxSlope":90,
   "erodeIterations":0,
   "autoLinkGrids":false,
   "autoLinkDistLimit":10,
   "neighbours":"Eight",
   "cutCorners":true,
   "penaltyPositionOffset":0,
   "penaltyPosition":false,
   "penaltyPositionFactor":1,
   "penaltyAngle":false,
   "penaltyAngleFactor":100,
   "open":true,
   "infoScreenOpen":false
   ...
}

노드 정보가 직렬화된 데이터에 포함된 경우, JSON으로 포함하기에는 공간을 너무 많이 차지하므로 대신 이진 데이터로 작성됩니다. 각 그래프 유형에는 노드 데이터를 직렬화하는 자체 코드가 있습니다. 이는 각 그래프의 SerializeExtraInfo 및 DeserializeExtraInfo 메서드에 의해 처리됩니다.

User Created Connections

NodeLink2 컴포넌트도 직렬화되며, 직렬화 시 해당 컴포넌트의 ID를 저장하고 그래프가 역직렬화될 때 해당 컴포넌트를 찾으려고 시도합니다. 이는 정적 맵에서는 잘 작동하지만, 런타임 중에 생성된 객체의 경우 다양한 객체를 추적할 좋은 방법이 없으므로, 저장된 데이터에 링크를 포함하지 않는 것이 좋을 수 있습니다(링크가 비활성화되어 있는지 확인). 그런 다음 그래프가 로드된 후 링크를 활성화하면 됩니다.

'유니티 에셋 > A* Pathfinding project pro' 카테고리의 다른 글

Large worlds  (0) 2024.05.27
Accessing graph data  (0) 2024.05.27
Working with tags  (0) 2024.05.27
Navmesh Cutting  (0) 2024.05.27
Using nodes  (0) 2024.05.27

+ Recent posts