A* Pathfinding Project를 최신 버전으로 업그레이드하기

Contents

  • 4.x에서 5.0으로 업그레이드
    • 업데이트 설치
    • Seeker.StartPath 대신 ai.SetPath 사용
    • Seeker.pathCallback 사용 중단
    • 스캔은 Awake 대신 OnEnable에서 발생
    • 경로 찾기 태그는 이제 구조체로 표현
    • RVOSquareObstacle 지원 제거
    • RVONavmesh 사용 중단
    • 커스텀 그래프 인터페이스 변경
    • 그래프 업데이트는 비동기적으로 더 많은 작업 수행
    • 그리드 그래프의 경우 GraphUpdateObject.Apply 대신 ApplyJob 사용
    • 더 나은 성능을 위한 그리드 노드 일괄 업데이트
    • 육각형 그래프의 비용이 잘못된 비율로 조정됨
    • NavGraph.GetNearest는 이제 항상 제약 조건을 고려
    • 이동 스크립트는 더 이상 Update 및 FixedUpdate를 사용하지 않음
    • ProceduralGridMover는 이제 ProceduralGraphMover로 변경
    • 네임스페이스 구조
  •  일반 업그레이드 노트

4.x에서 5.0으로 업그레이드

5.0 릴리스에는 많은 변경 사항이 있습니다. 대부분의 경우 업그레이드는 원활하게 진행되며 코드 변경이 필요 없지만, 몇 가지 주요 변경 사항으로 인해 코드나 설정을 업데이트해야 할 수 있습니다.

업데이트 설치

업그레이드할 때는 새 버전을 가져오기 전에 기존 AstarPathfindingProject 폴더를 삭제해야 합니다. 그렇지 않으면 오래된 파일이 남아 문제를 일으킬 수 있습니다.

Installation Guide 참조

 

Seeker.StartPath 대신 ai.SetPath 사용

내장된 이동 스크립트는 이제 부착된 Seeker 컴포넌트가 계산한 모든 경로를 청취하지 않고, 요청한 경로만 청취합니다. 다른 스크립트에서 seeker.StartPath를 호출하고 이동 스크립트가 경로를 따라가도록 의존하고 있었다면, 이제  ai.SetPath 를 호출해야 합니다. 지금은 호환성 코드가 있어 작동하지만, 경고 메시지가 계속 표시됩니다.

참고:  
자체 커스텀 이동 스크립트를 작성한 경우, 이 변경 사항은 영향을 미치지 않습니다. 이 경우 계속해서 Seeker를 사용하면 됩니다.

 

이전에는 코드가 다음과 같을 수 있습니다:

var ai = GetComponent<IAstarAI>();
var seeker = GetComponent<Seeker>();
seeker.StartPath(ai.position, ai.destination);

위 코드는 다음과 같이 변경해야 합니다:

var ai = GetComponent<IAstarAI>();
var path = ABPath.Construct(ai.position, ai.destination);
ai.SetPath(path);

 

참조: Searching for paths 에 대한 자세한 정보


Seeker.pathCallback 사용 중단

Seeker.pathCallback 필드는 이제 사용 중단되었습니다. 대신 `StartPath` 메서드에 콜백을 전달해야 합니다.

참고:  
이 변경 사항은 자체 이동 스크립트를 작성하는 경우에만 영향을 미칩니다. 내장된 이동 스크립트를 사용하는 경우, 이전 섹션에서 설명한 대로 `ai.SetPath`를 사용해야 합니다.


이전 코드 예시:

Seeker seeker;

void OnEnable () {
    // Seeker 컴포넌트를 가져옵니다.
    seeker = GetComponent<Seeker>();
    // 경로가 완료될 때 호출될 콜백을 추가합니다.
    seeker.pathCallback += OnPathComplete;
}

void OnDisable () {
    // 경로 완료 콜백을 제거합니다.
    seeker.pathCallback -= OnPathComplete;
}

void DoSomething() {
    // 지정된 위치에서 대상 위치까지의 경로 찾기를 시작합니다.
    seeker.StartPath(transform.position, target.position);
}

void OnPathComplete (Path path) {
    // 경로와 관련된 작업을 수행합니다.
}

 

새 코드 예시:

Seeker seeker;
OnPathDelegate onPathComplete;

void OnEnable () {
    // Seeker 컴포넌트를 가져옵니다.
    seeker = GetComponent<Seeker>();
    // OnPathComplete 콜백을 onPathComplete 변수에 할당합니다.
    onPathComplete = OnPathComplete;
}

void DoSomething() {
    // 지정된 위치에서 대상 위치까지의 경로 찾기를 시작하며,
    // 경로가 완료되면 onPathComplete 콜백이 호출됩니다.
    seeker.StartPath(transform.position, target.position, onPathComplete);
}

void OnPathComplete (Path path) {
    // 경로와 관련된 작업을 수행합니다.
}

 

참조: Searching for paths 에 대한 자세한 정보

 

스캔은 Awake 대신 OnEnable에서 발생

게임 시작 시 스캔이 초기 Awake 대신 초기 OnEnable에서 발생합니다. 일반적으로 이는 문제를 일으키지 않지만, 매우 특정한 초기화 순서에 의존하는 경우 문제가 발생할 수 있습니다.

경로 찾기 태그는 이제 구조체로 표현

일부 태그 필드의 타입이 `int`에서  PathfindingTag 로 변경되었습니다. 이전에 태그를 할당한 경우 이제 이를 `PathfindingTag`로 변환해야 합니다:

GetComponent<GraphUpdateScene>().setTag = new PathfindingTag((uint)tag);


또는  PathfindingTag.FromName 메서드를 사용하여 문자열에서 태그를 가져올 수 있습니다.

인스펙터에 태그 열거형을 표시하려면 PathfindingTag 유형의 public 필드를 노출하면 됩니다. 이렇게 하면 태그 이름이 드롭다운으로 자동 표시됩니다.

RVOSquareObstacle 지원 제거

RVOSquareObstacle은 더 이상 지원되지 않습니다. 이는 성능이 좋지 않고 제대로 작동하지 않았기 때문입니다.

하지만 로컬 회피 시스템이 이제 경로 찾기 그래프를 더 잘 고려하게 되었기 때문에(`RVOSimulator` 컴포넌트에서 이 기능을 활성화하면), 그래프 업데이트를 사용하여 경로 찾기 그래프를 업데이트할 수 있습니다.

RVONavmesh 사용 중단

RVONavmesh 컴포넌트는 사용 중단되었습니다. 이제 RVOSimulator.useNavmeshAsObstacle 옵션을 활성화하여 자동으로 처리됩니다.

커스텀 그래프 인터페이스 변경

자체 커스텀 그래프 클래스를 작성한 경우, 여러 메서드의 시그니처가 변경되었습니다.

자세한 내용은  Writing Graph Generators 에서 확인할 수 있습니다.

그래프 업데이트가 비동기적으로 더 많은 작업 수행

그리드 그래프 및 Recast 그래프에 대한 그래프 업데이트는 이제 더 많은 작업을 비동기적으로 수행합니다. 이는 일반적으로 프레임 속도를 개선하지만, 그래프 업데이트가 완료되는 데 더 많은 프레임이 걸릴 수 있습니다.

그래프 업데이트가 즉시 완료되도록 하려면  AstarPath.FlushGraphUpdates 를 호출할 수 있습니다.

그리드 그래프의 경우 GraphUpdateObject.Apply 대신 ApplyJob 사용

그리드 그래프에 대한 그래프 업데이트는 더 이상 `GraphUpdateObject.Apply` 메서드를 호출하지 않고, 대신 `GraphUpdateObject.ApplyJob` 메서드를 호출합니다. 커스텀 그래프 업데이트를 위해 `GraphUpdateObject`를 상속한 경우, 코드를 Burst와 호환되도록 변환해야 합니다.

참조:  
Writing Custom Grid Graph Rules 에도 관심이 있을 수 있습니다.

 

 

그리드 노드 일괄 업데이트로 성능 향상

새로운 Burst 및 작업 시스템 덕분에 개별 노드 업데이트는 이전보다 약간 느려졌지만, 일괄 업데이트는 훨씬 빠를 수 있습니다.

기존 코드에서 노드 이동 가능성을 수동으로 업데이트했다면 다음과 같을 수 있습니다:

var grid = AstarPath.active.data.gridGraph;
grid.GetNodes(node => {
    if (someCondition) {
        node.Walkable = false;
    }
});
grid.GetNodes(node => grid.CalculateConnections(node);

이제 다음과 같이 변경해야 합니다:

var grid = AstarPath.active.data.gridGraph;
grid.GetNodes(node => {
    if (someCondition) {
        node.Walkable = false;
    }
});
grid.RecalculateAllConnections();

또는 새로운 편의 메서드  GridGraph.SetWalkability 를 사용할 수 있습니다:

AstarPath.active.AddWorkItem(() => {
    var grid = AstarPath.active.data.gridGraph;
    // 그래프의 왼쪽 상단 모서리에 있는 10x10 사각형의 모든 노드를 이동 불가로 표시합니다.
    grid.SetWalkability(new bool[10*10], new IntRect(0, 0, 9, 9));
});


비슷하게, 여러 노드를 업데이트하기 위해  GridGraph.CalculateConnectionsForCellAndNeighbour 를 사용해 왔다면, GridGraph.RecalculateAllConnections 또는 GridGraph.RecalculateConnectionsInRegion 을 사용하는 것이 좋습니다. 한두 개의 노드만 업데이트하는 경우에는 GridGraph.CalculateConnectionsForCellAndNeighbours 를 계속 사용하는 것이 괜찮습니다.

그래프의 더 복잡한 업데이트를 수행하는 경우, 대신 커스텀 그리드 그래프 규칙을 작성하는 것이 좋습니다. 그리드 그래프 규칙은 5.0의 새로운 기능으로, 스캐닝 프로세스와 훨씬 더 긴밀하게 통합되는 코드를 작성할 수 있게 합니다. 이는 또한 그래프 업데이트 및 ProceduralGraphMover 컴포넌트와 자동으로 작동함을 의미합니다.

Writing Custom Grid Graph Rules 참조

 

 

육각형 그래프의 비용이 잘못된 비율로 조정됨

육각형 그래프의 노드 간 비용이 sqrt(3/2)≈1.22배로 너무 크게 설정되었습니다. 이제 연결 비용은 노드 간 거리의 약 1000배로 설정됩니다.

예를 들어, 육각형 너비를 1로 설정한 경우, 인접한 두 육각형 간 이동 비용은 이전의 1224 대신 이제 1000이 됩니다. 대부분의 사용자에게는 영향을 미치지 않지만, 경로 찾기 성능이 약간 향상될 수 있습니다.

그래프에 페널티를 사용한 경우, 동일한 동작을 얻기 위해 페널티를 1.22로 나누어야 할 수 있습니다. 비슷하게, ConstantPath 를 사용하여 노드 집합을 얻은 경우, `maxGScore` 매개변수를 1.22로 나누어야 할 수 있습니다.

NavGraph.GetNearest는 이제 항상 제약 조건을 고려

NavGraph.GetNearest는 이제 항상 제약 조건을 고려합니다. 이전에는 그래프 유형에 따라 달라졌으며 일관된 결과를 얻기가 어려웠습니다. `NavGraph.GetNearestForce` 메서드는 제거되었으며, 이제 `NavGraph.GetNearest` 메서드로 대체되었습니다.

참고:  
 AstarPath.GetNearest 와 혼동하지 마세요.  AstarPath.GetNearest 는 항상 제약 조건을 고려했습니다.

 

이동 스크립트는 더 이상 Update 및 FixedUpdate를 사용하지 않음

`AIPath` 및 `RichAI` 스크립트는 더 이상 `Update` 및 `FixedUpdate` 메서드를 사용하지 않습니다. 대신 모든 특정 타입의 컴포넌트를 한 번에 처리할 수 있는 별도의 스크립트( BatchedEvents )를 사용합니다. 이는 약간 더 빠르며 AIBase.rvoDensityBehavior 구현에 필요합니다. `Update` 또는 `FixedUpdate` 메서드를 재정의해 왔다면, 대신 `OnUpdate` 메서드를 재정의하도록 코드를 변경해야 합니다.

ProceduralGridMover는 이제 ProceduralGraphMover로 변경

ProceduralGridMover 컴포넌트는 이제  ProceduralGraphMover 로 이름이 변경되었습니다. 이는 이제 그리드뿐만 아니라 더 많은 것을 지원하기 때문입니다.

스크립트에서 이를 참조하고 있다면, 참조 이름을 변경해야 합니다.

네임스페이스 구조

네임스페이스 구조가 크게 개선되었습니다. 대부분의 변경 사항은 사용자가 자주 사용하지 않는 내부 클래스에 적용되었습니다. `using` 문을 약간 조정해야 할 수 있습니다. 주요 변경 사항은 다음과 같습니다:

불행히도 C#은 public 네임스페이스 별칭을 지원하지 않으므로, 이러한 변경 사항은 이전 버전과의 호환성을 유지할 수 없습니다.

일반 업그레이드 노트

업그레이드에 문제가 있는 경우, Unity에서 `AstarPathfindingProject` 폴더를 삭제하고 패키지를 다시 가져와 보세요. 이렇게 하면 프로젝트에 더 이상 포함되지 않은 오래된 스크립트를 제거하는 데 도움이 될 수 있습니다. UnityPackages는 디렉토리를 병합하므로, 여전히 남아 있을 수 있습니다.

클래스에 일부 멤버나 함수가 존재하지 않는다는 컴파일러 메시지가 표시되는 경우, 이는 프로젝트에 전역 네임스페이스에 해당 이름의 클래스가 포함되어 있기 때문일 가능성이 큽니다. 이로 인해 클래스 간에 충돌이 발생합니다. 이를 해결하는 가장 간단한 방법은 충돌하는 클래스를 네임스페이스에 넣거나 이름을 변경하는 것입니다.

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

Frequently Asked Questions  (0) 2024.05.29
Bitmask Tutorial  (0) 2024.05.29
Misc  (0) 2024.05.28
Deploying for mobile/uwp  (0) 2024.05.28
Optimization > Compiler Directives  (0) 2024.05.28

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

Bitmask Tutorial  (0) 2024.05.29
Upgrade Guide  (0) 2024.05.29
Deploying for mobile/uwp  (0) 2024.05.28
Optimization > Compiler Directives  (0) 2024.05.28
Optimization > Pooling  (0) 2024.05.28

iPhone/Android 또는 UWP(Universal Windows Platform)용 A* Pathfinding Project 작업

여기에서 설명하는 대부분의 사항은 iPhone과 Android 모두에 적용됩니다. 그러나 iPhone은 더 제한적이므로 호환성을 위해 더 큰 주의가 필요합니다.

Universal Windows Platform (UWP)

Unity는 일부 이유로 UnityPackage 파일과 함께 일부 .dll 파일의 메타데이터를 포함하지 않습니다. UWP에서 작동하도록 하려면 Unity 프로젝트에서 `Pathfinding.Ionic.Zip.dll` 파일을 찾아서 UWP 빌드 시 *제외*되도록 설정해야 합니다. 이것만 하면 UWP에서 제대로 작동할 것입니다.

iPhone

A* Pathfinding Project는 대부분 iPhone에서도 바로 작동합니다. 그러나 스트리핑(어셈블리 또는 바이트코드)을 사용하는 경우, `link.xml` 파일을 찾아야 합니다. 이 파일은 `Assets/AstarPathfindingProject/link.xml`에 있으며, `Assets/link.xml`에 배치해야 합니다. 이 파일은 AOT(사전 컴파일) 컴파일러에 파일에 언급된 클래스를 제거하지 않도록 지시합니다. 이 작업을 수행하지 않으면, 예를 들어 캐싱을 시도할 때 오류가 발생할 수 있습니다.

마이크로 mscorlib 사용은 너무 많은 .Net 부분이 제거되므로 지원되지 않습니다.

"Fast But No Exceptions" 옵션을 사용하는 경우, 일부 리플렉션 코드를 사용할 수 없으므로 `ASTAR_FAST_NO_EXCEPTIONS` 지시문을 활성화해야 합니다. 프로 버전을 사용하는 경우, A* Inspector의 Optimizations 탭을 열고 `ASTAR_FAST_NO_EXCEPTIONS`을 활성화한 후 Apply를 클릭하십시오. 무료 버전을 사용하는 경우, `AstarData.cs` 스크립트(Core 폴더에 있음)를 열고 상단에 다음 줄을 추가(또는 주석 해제)하십시오:

#define ASTAR_FAST_NO_EXCEPTIONS


또한  JsonSerializer.cs 에서도 동일한 작업을 수행하십시오.

이렇게 하면 기본 그래프 유형에 대한 참조가 하드코딩됩니다. 사용자 정의 그래프 유형을 작성한 경우, 해당 유형을  AstarData.cs 의 `DefaultGraphTypes` 변수에 정의된 하드코딩된 목록에 추가해야 합니다.

참조:
Pathfinding.AstarData.DefaultGraphTypes



Optimize for mobile

iPhone용으로 배포할 때 시작 시간을 줄이기 위해 캐싱 시작을 사용하는 것이 좋습니다. 특히 Recast 그래프를 사용하는 경우에 유용합니다.

참조:
Saving and Loading Graphs


또한 A* Inspector -> Optimizations 아래의 다양한 옵션을 확인하여 특정 경우에 성능을 향상시킬 수 있습니다.

참조:
Compiler Directives

 

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

Upgrade Guide  (0) 2024.05.29
Misc  (0) 2024.05.28
Optimization > Compiler Directives  (0) 2024.05.28
Optimization > Pooling  (0) 2024.05.28
Optimization > Heuristic Optimization  (0) 2024.05.28

http://www.arongranberg.com/astar/buy

패키지 최적화를 위한 컴파일러 지시문 사용 개요

A*  Pathfinding Project의 프로 버전에는 A* Inspector에 "Optimization"이라는 탭이 있습니다.


이 탭은 프로젝트에서 컴파일러 지시문이 나열된 위치를 검색합니다. 컴파일러 지시문은 다른 코드가 컴파일에 포함될지 여부를 제어하는 코드 조각입니다.

#define DEBUG

public void Start () {
#if DEBUG
    Debug.Log ("DEBUG 컴파일러 지시문이 정의되었습니다");
#else
    Debug.Log ("DEBUG 지시문이 정의되지 않았습니다");
#endif
}



보시다시피, 일반적인 IF 문처럼 작동합니다. 컴파일러 지시문의 장점은 런타임 오버헤드가 전혀 없으며, 모두 컴파일 시간에 평가된다는 점입니다. A*  Pathfinding Project는 몇 가지 사용자 지정 가능한 측면을 가지고 있으며, 이는 보통 코드 수정을 필요로 하지만, 컴파일러 지시문으로 해결할 수 있습니다.

지시문은 다양한 최적화를 적용하거나(각각의 설명 참조) 디버깅 메시지를 활성화합니다(개발자가 아닌 다른 사람에게는 별로 유용하지 않을 수 있습니다).

지시문이 활성화되었는지 여부는 플레이어 설정의 "Scripting Define Symbols" 필드에 저장되며, 이는 Unity 프로젝트의 모든 씬에서 설정이 공유됨을 의미합니다.

모바일을 대상으로 하는 경우, 빌드된 플레이어의 파일 크기를 최대한 줄이는 것이 좋습니다. 이 경우 `ASTAR_NO_ZIP` 옵션을 사용하여 DotNetZip 라이브러리에 대한 의존성을 제거할 수 있습니다. 최적화 패널에서 옵션을 활성화한 후, `Assets/AstarPathfindingProject/Plugins/DotNetZip` 폴더의 dll 파일을 제거하면 몇 백 KB를 줄일 수 있습니다. 그러나 이렇게 하면 캐시된 시작을 사용할 때 캐시 크기가 훨씬 커집니다.

A* Pro 기능
이 기능은 A* Pathfinding Project Pro 기능입니다. 이 함수/클래스/변수는 A* Pathfinding Project의 무료 버전에는 존재하지 않거나 기능이 제한될 수 있습니다. Pro 버전은 여기에서 구매할 수 있습니다.

 

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

Misc  (0) 2024.05.28
Deploying for mobile/uwp  (0) 2024.05.28
Optimization > Pooling  (0) 2024.05.28
Optimization > Heuristic Optimization  (0) 2024.05.28
Optimization  (0) 2024.05.28

Pooling

객체 풀링은 가비지 컬렉터의 부하를 줄이기 위해 사용됩니다.

풀링은 시스템을 많이 사용하거나 저사양 하드웨어(예: 모바일)에서 실행할 때 성능을 극대화하는 훌륭한 방법입니다. Mono 가비지 컬렉터는 더 이상 사용되지 않는 객체를 잘 수집하지만, 큰 문제는 GC가 실행될 때마다 게임을 일시적으로 멈추어야 한다는 점입니다. 이는 게임에서 몇 초마다 작은 끊김 현상으로 나타날 수 있습니다. 특히 메모리와 프로세서 성능이 제한된 모바일에서는 큰 문제가 됩니다.

이 문제를 해결하는 한 가지 방법은 대부분의 객체를 풀링하는 것입니다. 객체가 더 이상 사용되지 않으면 풀에 넣고, 이후 동일한 유형의 새 인스턴스가 필요할 때 풀에서 쉽게 얻을 수 있는 객체가 있는지 확인합니다. 풀을 사용하면 GC의 부하가 줄어들어 게임의 끊김 현상이 줄어듭니다.

Path Pooling

A* Pathfinding Project에서 풀링은 주로 경로와 리스트에 사용됩니다. 이는 가장 많이 할당되는 것이기 때문입니다. 스크립트에 풀링 로직을 추가하는 것은 매우 적은 코드로 가능하지만, 올바르게 수행하지 않으면 오류가 발생하기 쉽습니다.

A* Pathfinding Project의 풀링은 일종의 수동 참조 카운팅에 기반합니다. 경로 객체를 사용하기 시작할 때 .Claim 함수를 호출해야 하고, 더 이상 사용하지 않을 때(예: 새 경로로 대체될 때)는 Release 함수를 호출해야 합니다. 경로에 대한 Release 함수가 호출되고 다른 스크립트가 사용하지 않을 때, 경로는 언제든지 재활용될 수 있습니다. 이는 변수들이 언제든지 초기화될 수 있음을 의미합니다. 따라서 경로에 대해 Release를 호출한 후에는 해당 경로에 대한 참조를 유지해서는 안 됩니다. 경로 클래스의 vectorPath 및 path 리스트도 경로가 재활용될 때 재활용됩니다. 따라서 이를 다시 사용하지 않도록 주의해야 합니다. 만약 vectorPath/path 변수만 사용하고 경로를 재활용하고 싶다면, 이를 로컬 변수에 저장하고 경로 객체의 vectorPath/path 변수를 null로 설정한 후 경로를 릴리스하십시오. 변수가 null이므로 경로 객체는 이를 재활용할 수 없으며, 따라서 안전하게 사용할 수 있습니다.

참조
Pathfinding.Path.Claim
Pathfinding.Path.Release


경로에 대해 Claim이나 Release를 호출하지 않으면, 단순히 풀링되지 않습니다. 따라서 풀링을 신경 쓰고 싶지 않다면 신경 쓰지 않아도 됩니다. 경로에 대해 Claim을 호출하지만 Release를 호출하지 않고 모든 참조를 제거하면, 여전히 가비지 컬렉터에 의해 수집되지만 풀로 반환되지는 않습니다. Claim을 호출하지 않고 Release를 호출하거나, 동일한 객체에 대해 여러 번 Release를 호출하면 오류가 로그에 기록됩니다.

다음은 경로 풀링 사용의 예입니다:

public class SomeAI : MonoBehaviour {
    ABPath path;

    public IEnumerator Start () {
        while (true) {
            GetComponent<Seeker>().StartPath(transform.position, transform.position + transform.forward * 10, OnPathComplete);
            yield return new WaitForSeconds(1); // Added to prevent infinite loop in this example
        }
    }

    void OnPathComplete (Path p) {
        // 이전 경로를 풀로 반환
        if (path != null) path.Release(this);

        path = p as ABPath;

        // 새로운 경로 요청
        path.Claim(this);
    }

    void Update () {
        // 에디터에서 경로 그리기
        if (path != null && path.vectorPath != null) {
            for (int i = 0; i < path.vectorPath.Count - 1; i++) {
                Debug.DrawLine(path.vectorPath[i], path.vectorPath[i + 1], Color.green);
            }
        }
    }
}


경로가 풀링될 때, vectorPath 및 path 필드(및 경로 유형에 더 많은 리스트가 있는 경우)는 또한 풀링됩니다. 따라서 경로 객체에서 vectorPath를 가져오고 경로 객체를 풀링한 후에도 계속 vectorPath를 사용하는 것은 안전하지 않습니다.

Claim 및 Release 함수는 객체 참조를 가져옵니다. 이는 사용자 오류 가능성을 줄이기 위해 주로 사용됩니다. 동일한 객체를 사용하여 경로가 여러 번 릴리스되거나 여러 번 클레임되지 않도록 오류 검사가 수행됩니다.

List Pooling

대부분의 사용자에게는 중요하지 않을 수 있지만, 고급 사용자에게는 관련이 있을 수 있습니다. 이 프로젝트는 제네릭 리스트의 풀링도 포함합니다. 이는 시스템이 매번 새로운 리스트를 할당하지 않도록 내부적으로 사용됩니다. 리스트 풀링 클래스는 사용하기 매우 간단하며,  Pathfinding.Util.ListPool.Claim 을 사용하여 참조를 얻고, 완료되면  Pathfinding.Util.ListPool.Release 를 사용하여 해제합니다. ListPool 클래스는 타입 인수를 사용하므로 모든 리스트 타입에 사용할 수 있습니다.

// 리스트 참조 얻기
List<int> myList = Pathfinding.Util.ListPool<int>.Claim();

// 작업 수행
for (int i = 0; i < 100; i++) myList.Add(i);
int fiftytwo = myList[52];

// 해제
Pathfinding.Util.ListPool<int>.Release(ref myList);
// Release 호출 시 'ref' 매개변수를 사용하여 myList 변수를 동시에 null로 설정하여
// 리스트를 실수로 다시 사용하는 것을 방지합니다.



Debugging

풀링 설정이 복잡한 스크립트와 함께 사용되는 경우 설정이 어렵고 결과를 즉시 확인할 수 없기 때문에 디버거를 사용하는 것이 좋습니다. A*  Pathfinding Project에는 디버거가 포함되어 있습니다. Components ->  Pathfinding  -> Debugger를 GameObject에 추가하십시오.

Pathfinding.AstarDebugger 에 대한 자세한 정보는 참조하십시오.


또한 최적화 탭에서 ASTAR_POOL_DEBUG 정의를 활성화하는 것도 매우 유용합니다. 무료 버전만 있는 경우(최적화는 프로 전용 기능이므로),  Path.cs 파일을 열고 ASTAR_POOL_DEBUG를 언급하는 상단의 줄을 주석 해제하십시오.

이를 활성화하면 파괴된 모든 경로가 풀링되었는지, 잘못된 사용이 있었는지에 대한 정보를 로그에 기록합니다.

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

Deploying for mobile/uwp  (0) 2024.05.28
Optimization > Compiler Directives  (0) 2024.05.28
Optimization > Heuristic Optimization  (0) 2024.05.28
Optimization  (0) 2024.05.28
Deploying  (0) 2024.05.28

Heuristic Optimization

휴리스틱 최적화를 사용하여 상당한 속도 향상을 얻는 방법에 대한 튜토리얼입니다.

경로 찾기 검색이 이루어질 때 일반적으로  heuristic 이 사용됩니다. 휴리스틱은 목표까지 얼마나 멀리 있는지를 대략적으로 추정하는 방법입니다. 일반적으로 실제  euclidean distance 를 직접 사용합니다. 이는 빠르고 일반적으로 상대적으로 좋은 결과를 제공하기 때문입니다. 하지만 작은 장애물만 있는 열린 공간이 아닌 세계에서는 이 추정이 좋지 않습니다. 그 결과, 휴리스틱이 더 나았더라면 필요하지 않았을 많은 노드를 검색하게 됩니다.

A* Inspector -> Settings -> Heuristic Optimization
휴리스틱 최적화 설정을 보유합니다.

Heuristic Optimization 참조
A* Pro 기능
이 기능은 A* Pathfinding Project Pro 기능입니다. 이 함수/클래스/변수는 A* Pathfinding Project의 무료 버전에는 존재하지 않거나 기능이 제한될 수 있습니다. Pro 버전은 여기에서 구매할 수 있습니다.
이 설정은  AstarPath.euclideanEmbedding 멤버에 해당합니다.



Results

이 기술은 목표를 찾기 위해 검색해야 하는 노드 수를 크게 줄일 수 있습니다. 이는 성능을 크게 향상시킬 수 있습니다.

아래의 두 이미지를 비교해 보십시오. 첫 번째 이미지에서는 이 최적화가 비활성화되어 있고, 두 번째 이미지에서는 활성화되어 있습니다. 두 번째 이미지에서는 검색이 더 정보에 기반하여 불필요한 방향을 피할 수 있습니다.

휴리스틱 최적화 비활성화



휴리스틱 최적화 활성화



Background

세계가 정적이거나 업데이트가 매우 드문 경우, 노드 간의 거리를 미리 계산하고 훨씬 더 나은 휴리스틱을 얻을 수 있는 기술을 사용할 수 있습니다. 이는 많은 경우 경로 찾기 성능을 10배 향상시킬 수 있습니다.

최적의 휴리스틱은 물론 그래프의 모든 노드 간 거리를 알고 있을 때입니다. 하지만 이는 계산에 오랜 시간이 걸리고 많은 공간을 차지하기 때문에 실용적이지 않습니다.

따라서 몇몇 노드(이후 "피벗 포인트"라 부름)를 선택하고 그 노드에서 그래프의 모든 다른 노드까지의 거리를 계산합니다. 이를 통해 꽤 좋은 휴리스틱을 계산할 수 있습니다.

사용된 휴리스틱과 관계없이, A* 알고리즘은 항상 최단 경로에 있을 수 있는 모든 노드를 검색합니다. 따라서 이 기술은 예를 들어 큰 열린 그리드 그래프에서 성능 향상을 제공하지 않습니다. 왜냐하면 경로 검색은 어쨌든 최단 경로의 노드보다 훨씬 더 많이 검색하지 않기 때문입니다.

아래 이미지는 완전히 비어 있는 그리드 그래프와 3개의 다른 최적 경로를 보여줍니다. 알고리즘은 녹색 영역에 있는 모든 노드를 검색해야 합니다. 왜냐하면 그들은 모두 동일한 길이를 가지고 있기 때문입니다. 그리드에서는 많은 최적 경로가 있기 때문에 모든 노드가 최적 경로에 있습니다.


A*  Pathfinding Project는 수동으로 선택하는 것보다 더 좋은 피벗 포인트를 자동으로 선택하는 알고리즘을 가지고 있습니다. 피벗 포인트를 수동으로 배치하는 것보다 무작위로 선택하는 것이 더 나은 경우가 많습니다.

Placing Pivot Points Manually

이 피벗 포인트를 배치할 때 중요한 점은 이들이 세계의 막다른 곳에 있어야 한다는 것입니다. 많은 경로가 피벗 포인트로 확장될 수 있고 여전히 최단 경로가 될 때 가장 잘 작동합니다.

아래 이미지에서 보라색으로 표시된 피벗 포인트를 볼 수 있습니다. 왼쪽 하단의 에이전트가 녹색 원으로 경로를 요청했습니다.


게임에 특정한 지식을 적용할 수도 있습니다. 예를 들어 TD 게임에서는 거의 모든 유닛이 단일 목표로 이동합니다. 따라서 목표에 단일 피벗 포인트를 배치하면 모든 경로가 훨씬 빠르게 계산됩니다. 왜냐하면 그 지점까지의 최적 거리가 이미 알려져 있기 때문입니다.

Placing Pivot Points Automatically

두 가지 모드가 있습니다. 무작위로 모든 포인트를 선택하거나, 가능한 한 서로 멀리 떨어져 있는 노드를 선택하는 알고리즘을 적용하는 것입니다. 두 번째 방법은 훨씬 높은 품질의 휴리스틱을 제공하지만, 초기 거리 계산을 직렬로 수행해야 하므로 계산 속도가 느립니다.

아래 이미지에서 무작위로 선택한 5개의 포인트와 서로 멀리 떨어진 5개의 포인트를 비교할 수 있습니다. 서로 멀리 떨어진 포인트는 막다른 곳이나 맵의 구석에 배치되는 경향이 있어 매우 좋은 결과를 제공합니다.


사용할 피벗 포인트의 수는 다양합니다. 가장 좋은 방법은 다양한 값을 시도해보고 어떤 것이 게임에 가장 적합한지 확인하는 것입니다. 피벗 포인트가 100개를 넘으면 검색할 노드 수가 줄어드는 이득보다 오버헤드가 더 커집니다. 1에서 100 사이를 권장하며, 다양한 값을 시도해보고 어떤 것이 가장 적합한지 확인하십시오.

게임 시작 시 경로 찾기가 작동할 때까지 지연이 발생할 수 있습니다. 이는 휴리스틱 조회를 사전 처리하느라 바쁘기 때문입니다. 이 지연이 문제가 된다면 "Random" 모드를 사용하거나 피벗 포인트 수를 줄이십시오.

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

Optimization > Compiler Directives  (0) 2024.05.28
Optimization > Pooling  (0) 2024.05.28
Optimization  (0) 2024.05.28
Deploying  (0) 2024.05.28
Spherical Worlds  (0) 2024.05.28

성능을 향상시키기 위한 몇 가지 팁

시스템 성능을 높이는 다양한 방법이 있습니다.

하지만 먼저 프로파일링을 하세요! 최적화를 시도하기 전에, 프로파일러를 사용하여 게임의 어느 부분이 속도를 저하시키는지 파악해야 합니다. 멀티스레딩을 사용하는 경우, 경로 찾기는 별도의 경로 찾기 스레드에만 나타납니다(이것은 Unity 프로파일러에서 선택할 수 있습니다).

 

General tips

성능 평가 시 "Show Graphs"(A* 인스펙터 하단)가 비활성화되어 있는지 확인하십시오. 큰 그래프의 경우, 매 프레임마다 이를 그리는 오버헤드가 게임을 심각하게 느리게 할 수 있습니다(이는 에디터에만 적용되며 독립 실행형 게임에는 적용되지 않습니다).

Optimizing game startup

게임이 시작될 때 AstarPath 컴포넌트는 기본적으로 모든 그래프를 스캔합니다. 이는 그래프 설정 및 그래프 크기에 따라 시간이 걸릴 수 있습니다.

정적으로 고정된 월드가 있는 경우, 스캔된 그래프를 캐시하고 시작 시 캐시를 로드할 수 있습니다. 이에 대한 자세한 내용은 Saving and Loading Graphs 를 참조하십시오.

또는, 그래프가 스캔되는 동안 진행 막대를 표시하거나 게임을 완전히 멈추지 않으려면 비동기적으로 그래프를 스캔할 수 있습니다. 먼저 A* Inspector -> Settings -> Scan On Awake를 비활성화하십시오. 그런 다음 사용자 정의 스크립트에서 다음과 같이 비동기적으로 그래프를 스캔할 수 있습니다:

IEnumerator Start () {
    foreach (Progress progress in AstarPath.active.ScanAsync()) {
        Debug.Log("Scanning... " + progress.ToString());
        yield return null;
    }
}


그래프를 캐시하는 것이 옵션이 아닌 경우(예를 들어 동적 레벨이 있는 경우), 그래프 설정을 조정하여 스캔 속도를 높이거나 그래프 유형을 변경하는 것이 좋습니다. 일반적으로 그리드 그래프는 recast 그래프보다 스캔 속도가 빠르지만, 세계가 매우 큰 경우는 예외입니다. 그러나 경로 찾기는 보통 recast 그래프에서 더 빠릅니다. 다음 섹션에서는 다양한 그래프 유형에 대한 몇 가지 팁을 포함하고 있습니다.

Graph Types 에 대한 자세한 내용은 그래프 유형을 참조하십시오.

 

Optimizing Grid Graph Scanning

 

그리드 그래프를 스캔하는 시간을 줄이는 몇 가지 방법이 있습니다:

  • 가능하다면 해상도를 줄이십시오.
  • 완전히 평평한 세계가 있는 경우 높이 테스트를 비활성화하십시오.
  • 침식을 비활성화하십시오. 이는 작은 성능 오버헤드를 가집니다.
  • 충돌 테스트가 필요 없는 경우 이를 비활성화하십시오.

Optimizing Recast Graph Scanning

  • 셀 크기를 늘리십시오. 이는 그래프가 세계를 보컬화하는 해상도를 줄일 것입니다.
  • 타일링을 사용하고 적절한 크기의 타일을 사용하십시오. 64에서 256 보컬 사이의 값이 권장됩니다. 타일은 병렬로 스캔될 수 있어 다중 코어 컴퓨터에서 상당한 속도 향상을 제공할 수 있습니다. 그러나 각 타일에는 약간의 오버헤드가 있으므로 너무 작은 타일 크기는 스캔 속도를 느리게 합니다.
  • 콜라이더를 래스터화하십시오. 콜라이더는 일반적으로 메쉬보다 훨씬 간단하여 래스터화가 더 빠릅니다. 또한, 물리 엔진을 사용하여 효율적으로 쿼리할 수 있으므로 그래프 업데이트 성능이 향상됩니다.
  • 그래프의 경계 상자를 줄여 필요한 세계 부분만 덮도록 하십시오.

Optimizing Navmesh Graph Scanning

Navmesh 그래프를 스캔하는 데 걸리는 시간은 입력 메쉬의 삼각형 수에 거의 전적으로 의존합니다. 이를 줄일 수 있다면 그래프는 더 빠르게 스캔될 것입니다.

Optimizing Movement Scripts

이동 스크립트는 성능에 큰 영향을 미칠 수 있습니다. 포함된 다양한 이동 스크립트는 서로 다른 성능 특성을 가지고 있습니다.

  • AILerp 는 가장 빠르지만, 움직임이 매우 현실적이지 않아 게임에 적합하지 않을 수 있습니다.
  • AIPath 는 조금 느리지만 로컬 회피를 처리할 수 있으며 더 부드러운 움직임을 제공합니다(이는 게임에 따라 바람직할 수도 있습니다).
  • RichAI 는 가장 느리지만, 경로를 따를 때 AIPath보다 더 견고하며 메쉬 간 링크를 더 잘 지원합니다.
  • FollowerEntity 는 일반적으로 성능 측면에서 AILerp와 AIPath 사이에 있습니다. 멀티스레딩을 사용하여 메인 스레드를 차단하지 않지만, 여전히 많은 작업을 백그라운드에서 수행하며 다른 스크립트보다 더 복잡합니다. 현재 베타 상태이지만 대부분의 경우 AIPath 및 RichAI보다 추천합니다.

 

캐릭터에 CharacterController 또는 Rigidbody 컴포넌트를 부착하지 않는 것이 좋습니다. 이들은 상당히 느립니다. 이들이 부착되지 않은 경우, AIPath 및 RichAI 스크립트는 대신 단순한 레이캐스트를 사용하여 지면을 감지하며, 이는 일반적으로 훨씬 빠릅니다.

Movement scripts 에 대한 자세한 내용은 이동 스크립트를 참조하십시오.



Optimizing Pathfinding

경로 찾기는 실제로 성능 병목 현상이 아닐 때가 많습니다. 이는 큰 그리드 그래프와 많은 에이전트를 보유한 경우에만 병목 현상이 되기 쉽습니다. 프로파일러를 사용하여 경로 찾기 스레드가 매우 바쁜지 확인하십시오.

하지만 처리량이 병목 현상이 아니더라도 경로 찾기 지연 시간을 개선하는 것이 좋습니다. 지연 시간은 경로 요청이 발행된 후 단일 경로를 계산하는 데 걸리는 시간입니다. 많은 에이전트의 목적지를 한꺼번에 설정하면 높은 지연 시간으로 인해 일부 에이전트가 다른 에이전트보다 뒤처질 수 있습니다. 이들은 경로를 재계산하기 위해 차례를 기다려야 합니다.


위 그림에서 볼 수 있듯이, 210개의 에이전트가 동시에 새로운 목적지를 받으면서 경로 찾기 스레드가 경로를 재계산하느라 매우 바쁩니다. 그러나 지연 시간은 여전히 ​​매우 낮아 모든 경로가 다음 프레임이 시작되기 전에 계산됩니다. 이 경우 성능은 양호합니다.

경로 찾기 성능을 개선해야 하는 경우 다음 팁을 참고하십시오:

  • 가장 쉬운 방법은 멀티스레딩을 활성화하는 것입니다(A* Inspector -> Settings). 이렇게 하면 경로 찾기가 Unity 스레드 대신 별도의 스레드에서 실행되어 성능이 크게 향상될 수 있습니다. 요즘 거의 모든 컴퓨터와 심지어 전화기에도 많은 코어가 있기 때문입니다.
  • 경로 결과 로깅은 성능에 큰 영향을 미칩니다. 경로 찾기 처리량을 50%까지 줄이는 경우도 많습니다. 필요하지 않으면 경로 로깅을 비활성화해야 합니다. A* Inspector -> Settings -> Path Log Mode를 None으로 설정하십시오.
  • 새 경로가 계산되는 빈도를 줄이십시오.
    • 이동 스크립트의 Recalculate Paths Automatically 필드를  Dynamic 으로 설정하여 에이전트가 목표에서 멀리 떨어져 있을 때는 경로를 덜 자주 재계산하고, 목표가 많이 변경되었을 때는 더 자주 재계산하도록 합니다.
    •  EveryNSeconds 모드를 사용하는 경우 기간 필드를 늘려보십시오.
    • 자동 경로 재계산을 비활성화하고 필요할 때만 경로를 재계산하는 게임 전용 논리를 사용할 수도 있습니다.
  • 수정자의 품질 설정을 낮추십시오. 특히 SimpleSmoothModifier 가 경로를 나누는 세그먼트 수를 줄일 수 있습니다. AIPath 이동 스크립트는 경로 자체가 특히 부드럽지 않더라도 경로를 부드럽게 따르는 데 이미 매우 잘 작동합니다.
  • 그리드 그래프 대신 recast 그래프를 사용하는 것이 일반적으로 경로 찾기 성능을 향상시킵니다. recast 그래프는 동일한 영역을 덮기 위해 훨씬 적은 노드를 필요로 하기 때문입니다.
  • 정적 맵에서는 휴리스틱 최적화가 옵션이 될 수 있습니다.  Heuristic Optimization 를 참조하십시오.

More Tips

성능을 향상시키기 위한 더 많은 방법을 보려면 하위 페이지를 참조하십시오.

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

Optimization > Pooling  (0) 2024.05.28
Optimization > Heuristic Optimization  (0) 2024.05.28
Deploying  (0) 2024.05.28
Spherical Worlds  (0) 2024.05.28
Editing graph connections manually  (0) 2024.05.28

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

Optimization > Heuristic Optimization  (0) 2024.05.28
Optimization  (0) 2024.05.28
Spherical Worlds  (0) 2024.05.28
Editing graph connections manually  (0) 2024.05.28
Extending The System > Writing Modifiers  (0) 2024.05.28

비플래너 표면에서 경로 찾기를 사용하는 방법에 대한 튜토리얼

일부 게임에서는 행성이나 고리와 같이 항상 '위' 방향이 일정하지 않은 표면에서 경로 찾기 및 로컬 회피를 사용해야 할 수 있습니다. 아래 이미지에서 몇 가지 세계 형태의 예를 볼 수 있습니다. 하지만 원하는 만큼 복잡하게 만들 수 있습니다(아래의 몇 가지 팁을 참조하세요).

참고
패키지에는 구형 세계에 대해 경로 찾기 및 로컬 회피를 구성하는 방법을 보여주는 "Spherical"이라는 예제 장면이 포함되어 있습니다.

 

Configuring a graph


네비메시 그래프와 포인트 그래프 모두 사용할 수 있습니다. 그러나 대부분의 경우 네비메시 그래프를 권장합니다. 설정 방법은 네비메시 튜토리얼(예:  Creating a navmesh manually )을 따르며, 평면 대신 구와 같은 모양을 만든다는 점만 다릅니다.
네비메시 그래프 설정에서 'Recalculate Normals'를 비활성화해야 합니다. 이를 활성화한 상태에서는 Y+ 축을 기준으로 노멀을 재계산하기 때문에, 구형 세계에서는 올바르지 않게 됩니다.



Movement scripts

곡면을 따라 캐릭터를 이동시키려면 사용자 정의 이동 스크립트를 사용하거나 포함된 AIPathAlignedToSurface 컴포넌트를 사용할 수 있습니다. AIPathAlignedToSurface 스크립트는 AIPath에서 상속받아 곡면에 더 적합하도록 몇 가지를 변경합니다. 첫째, 바닥 아래의 노멀을 사용하여 표면에 맞게 정렬합니다. 둘째, 중력을 세계의 위 방향이 아닌 캐릭터의 위 방향에 상대적으로 만듭니다. 예를 들어 중력을 (0, -10, 0)으로 설정하면 캐릭터가 구의 아래쪽에 있어도 표면 쪽으로 끌립니다.

네비메시 그래프에서 높은 경로 품질을 위해  funnel modifier 를 사용하는 것이 좋습니다. 그러나 곡면에서 올바르게 작동하려면 splitAtEveryPortal 이 활성화되어 있어야 합니다.

메시 콜라이더를 지면으로 사용하는 경우, AIPathAlignedToSurface 스크립트는 표면 노멀을 보간하여 이동을 더 부드럽게 만듭니다. 그러나 이는 콜라이더에 사용된 메시가 읽기 가능한 경우에만 작동합니다. 메시 자산 가져오기에서 'Read/Write Enabled' 체크박스를 확인하세요.

Local avoidance

로컬 회피는 기본적으로 곡면에서 지원됩니다. 장면에 RVOSimulator를 추가하고 에이전트에 RVOController를 추가한 다음(자세한 내용은  Local Avoidance 참조) RVOSimulator의  movement plane option을 'Arbitrary'로 설정하면 됩니다. AIPathAlignedToSurface 스크립트는 RVOController에 표면의 방향을 알려주는 작업을 처리합니다. 사용자 정의 이동 스크립트를 작성하는 경우  RVOController.movementPlane 속성을 설정하여 방향을 업데이트해야 합니다.

Tips for good non-planar navmeshes

좋은 네비메시는 대략적으로 동일한 크기의 삼각형으로 구성되어야 하며, 삼각형이 너무 작으면 경로 찾기가 불필요하게 느려지고, 너무 크면 정밀도가 너무 낮아집니다. 내장된 이동 스크립트를 사용하는 경우 매우 급격한 표면 변화를 피해야 합니다. 예를 들어, 일반 큐브 대신 둥근 큐브를 사용하십시오.

아래에는 좋은 네비메시와 나쁜 네비메시의 예가 있습니다. 이들은 매우 간단한 예제 네비메시이지만, 피해야 할 일반적인 아이디어를 전달하기를 바랍니다.

추천하지 않음.
이 네비메시는 날카로운 모서리(이동하기 어려움)와 매우 큰 삼각형(좋은 경로를 찾기에는 너무 큼)이 포함되어 있습니다. 경로는 노드별로 검색됩니다.
추천하지 않음.
이 네비메시는 노드 크기가 더 적절하게 세분화되었지만 여전히 매우 날카로운 모서리가 있습니다.
추천하지 않음.
이 네비메시는 날카로운 모서리가 없지만 삼각형 크기가 매우 달라서 일반적으로 경로 품질에 좋지 않습니다.
추천.
이 네비메시는 좋습니다.
추천.
이 네비메시는 좋습니다.
추천하지 않음.
이 네비메시는 삼각형 크기가 매우 다릅니다(특히 극지방 근처). 일반적으로 경로 품질에 좋지 않습니다.
추천.
이 네비메시는 좋습니다.

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

Optimization  (0) 2024.05.28
Deploying  (0) 2024.05.28
Editing graph connections manually  (0) 2024.05.28
Extending The System > Writing Modifiers  (0) 2024.05.28
Extending The System > Writing Graph Generators  (0) 2024.05.28

그래프 구조 편집 방법

때로는 그래프가 거의 올바르지만, 약간 수정이 필요한 경우가 있습니다. 이는 포인트 그래프에서 가장 일반적이며, 이 페이지는 주로 해당 그래프 유형을 대상으로 합니다. 하지만 이 방법은 어느 정도 다른 그래프 유형에서도 작동합니다.

점프, 등반, 텔레포터 및 기타 특수 이동 로직을 처리하려면 Off-mesh links 링크를 참조하세요.

 

 

포인트 그래프에서 연결을 추가하거나, 기존 연결을 제거하거나, 일부 연결의 비용을 변경하려는 경우 NodeLink 컴포넌트를 사용할 수 있습니다. 포인트 그래프는 일반적으로 GameObjects의 컬렉션에서 생성됩니다. NodeLink 컴포넌트를 하나의 노드에 추가한 다음, 대상을 다른 노드로 설정할 수 있습니다. 옵션을 변경하여 두 노드 사이에 새 연결을 추가하거나, 이미 존재하는 연결을 제거하거나(있는 경우), 두 노드 사이의 연결 비용을 변경할 수 있습니다. 이 새로운 연결은 원래 포인트 그래프에 의해 생성된 것과 동일합니다.

 

그래프를 쉽게 수정할 수 있도록 몇 가지 키보드 단축키가 있습니다. Unity의 메뉴바 -> Edit -> Pathfinding에서 메뉴 항목을 찾을 수 있습니다.

  • alt+ctrl+L (macOS에서는 alt+cmd+L): 두 노드를 연결합니다. NodeLink 연결이 없으면 노드를 연결하고, 이미 연결된 경우 명시적으로 연결을 삭제합니다.
  • alt+ctrl+U (macOS에서는 alt+cmd+U): 두 노드의 연결을 해제합니다. NodeLink가 연결을 추가하거나 삭제하도록 구성되어 있는지와 상관없이 두 노드를 연결하는 NodeLink 컴포넌트를 제거합니다.
  • alt+ctrl+B (macOS에서는 alt+cmd+B): 선택한 GameObjects의 모든 NodeLink 컴포넌트를 제거합니다.

Editing graph connections using code

코드를 사용하여 그래프 연결을 수정할 수도 있습니다.

// 두 노드를 연결합니다.
var node1 = AstarPath.active.GetNearest(transform.position, NNConstraint.None).node;
var node2 = AstarPath.active.GetNearest(transform.position + Vector3.right, NNConstraint.None).node;
var cost = (uint)(node2.position - node1.position).costMagnitude;

GraphNode.Connect(node1, node2, cost, OffMeshLinks.Directionality.TwoWay);

 

참조
GraphNode.Connect
GraphNode.Disconnect
GraphNode.ContainsOutgoingConnection
Graph Updates
Creating graphs during runtime
Graph Types

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

Deploying  (0) 2024.05.28
Spherical Worlds  (0) 2024.05.28
Extending The System > Writing Modifiers  (0) 2024.05.28
Extending The System > Writing Graph Generators  (0) 2024.05.28
Extending The System  (0) 2024.05.28

+ Recent posts