본문으로 건너뛰기

A* 길찾기

AStarPathfinder는 격자 기반 A* 알고리즘으로 두 지점 사이의 최단 경로를 탐색합니다. 4방향 및 대각선(8방향) 이동을 지원하며, 이진 최소 힙으로 효율적인 탐색을 수행합니다.

빠른 시작

1. AStarGridBaker로 씬 자동 스캔

씬의 Collider2D를 스캔해 격자를 자동 생성하는 컴포넌트입니다.

  1. 빈 GameObject에 A* Grid Baker 컴포넌트 추가
  2. Inspector에서 격자 크기와 장애물 레이어 설정
  3. Scene 뷰에서 초록(이동 가능) / 빨강(장애물) Gizmo로 확인
var baker = GetComponent<AStarGridBaker>();

// 월드 좌표 → 격자 좌표 변환
Vector2Int start = baker.WorldToCell(player.position);
Vector2Int end = baker.WorldToCell(targetPosition);

// 경로 탐색 (대각선 허용)
var path = AStarPathfinder.FindPath(baker.Grid, start, end, diagonal: true);

// 격자 좌표 → 월드 좌표로 이동
foreach (var cell in path)
{
Vector3 worldPos = baker.CellToWorld(cell);
// 이동 처리... (예: AchMover와 연계 시 아래 [AchMover 연계] 섹션 참고)
}

경로가 없으면 빈 List<Vector2Int>를 반환합니다.

AchFollower 연계

단순 추적에는 AchFollower를 사용하세요 — SetTarget()만 호출하면 끝입니다.

A* 경로를 따라 웨이포인트를 순서대로 이동해야 할 때는 코드로 직접 처리합니다.

var follower = GetComponent<AchFollower>();

foreach (var cell in path)
{
Vector2 waypoint = baker.CellToWorld(cell);
follower.SetTarget(/* 웨이포인트 위치를 가진 Transform */);

while (Vector2.Distance(transform.position, waypoint) > 0.05f)
await Task.Yield();
}

follower.ClearTarget();

웨이포인트 Transform이 없는 경우, AchFollower 대신 transform.position을 직접 조작하세요.

2. 코드로 격자 직접 생성

var grid = new AStarGrid(20, 20);

// 장애물 설정
grid.SetWalkable(5, 3, false);

// 이동 비용이 높은 지형 (늪지, 모래 등)
grid.SetCost(4, 4, 3f);

// 경로 탐색
var path = AStarPathfinder.FindPath(
grid,
start: new Vector2Int(0, 0),
end: new Vector2Int(19, 19),
diagonal: false);

AStarGridBaker 설정

필드설명
Width / Height격자 셀 수
CellSize셀 하나의 Unity 단위 크기
Origin격자 좌하단(0,0)의 기준 Transform (비우면 GameObject 위치 사용)
ObstacleLayer장애물로 판단할 레이어 마스크
DetectionRadius셀 당 장애물 감지 반경 (cellSize * 0.4 권장)
CostZones이동 비용 구역 배열 (Collider2D + 비용 값)
DrawGizmosScene 뷰 격자 시각화 표시 여부

이동 비용 구역 (Cost Zones)

특정 영역의 이동 비용을 높여 경로가 해당 구역을 우회하도록 유도합니다.

// Inspector의 Cost Zones 배열에 추가하거나,
// 동적 장애물 변경 후 재스캔
baker.Bake();
상황방법
벽이 Collider2D인 2D 게임AStarGridBaker ObstacleLayer 설정
Unity Tilemap 사용TilemapCollider2D를 장애물 레이어에 배치
문이 열리고 닫히는 등 동적 장애물baker.Bake() 재호출로 격자 재생성

AStarGrid API

var grid = new AStarGrid(width: 20, height: 20);

// bool 배열로 일괄 초기화
var grid2 = new AStarGrid(walkableMap: myBoolArray);

grid.SetWalkable(x, y, false); // 장애물 지정
grid.SetCost(x, y, 3f); // 이동 비용 설정 (1 이상)
bool ok = grid.IsWalkable(x, y);
float cost = grid.GetCost(x, y);
bool inRange = grid.IsInBounds(x, y);

AStarPathfinder API

List<Vector2Int> path = AStarPathfinder.FindPath(
grid: grid,
start: new Vector2Int(0, 0),
end: new Vector2Int(10, 10),
diagonal: true // false = 4방향, true = 8방향
);
파라미터설명
grid탐색할 AStarGrid
start시작 격자 좌표
end목표 격자 좌표
diagonal대각선 이동 허용 여부 (기본 false)

반환값: 시작점 제외, 도착점 포함 순서의 List<Vector2Int>. 경로가 없으면 빈 리스트.

알고리즘 상세

항목내용
탐색 방식A* (Open Set: 이진 최소 힙)
휴리스틱4방향 → Manhattan / 8방향 → Chebyshev
대각선 이동 비용√2 ≈ 1.414
셀 가중치AStarGrid.SetCost() 로 per-cell 비용 설정 가능
복잡도O((W×H) log(W×H))

⚠️ 코너 컷팅: 대각선 이동 시 두 직교 셀이 모두 막혀 있어도 대각선 셀이 열려 있으면 통과합니다. 벽 모서리에 박혀 보이는 게 신경 쓰이면 대각선 이동을 끄거나, 직접 인접 셀 검사 로직을 추가하세요.