경로 찾기 는 장애물을 피하고 (옵션으로) 위험한 재료나 정의된 지역에 도달하기 위해 캐릭터를 논리적 경로를 따라 이동하는 과정입니다.
탐색 시각화
경로 찾기 레이아웃과 디버깅을 지원하기 위해 Studio는 탐색 메쉬와 수정자 레이블을 렌더링할 수 있습니다.활성화하려면 3D 뷰포트의 오른쪽 상단에 있는 시각화 옵션 위젯에서 탐색 메시 및 경로 찾기 수정자를 토글하십시오.

탐색 메시 를 활성화하면 색상이 있는 영역에서 캐릭터가 걸을 수 있거나 수영할 수 있는 곳을 보여주고, 색상이 없는 영역은 차단됩니다.작은 화살표는 캐릭터가 점프하여 도달하려는 영역을 나타내며, 생성 경로를 설정할 때 으로 설정하면 됩니다.

경로 찾기 수정자 를 활성화하면 텍스트 레이블은 경로 찾기 수정자를 사용할 때 고려되는 특정 재료와 지역을 나타냅니다.

알려진 제한
경로 찾기 기능은 효율적인 처리와 최적의 이행보장하기 위해 특정 제한 사항이 있습니다.
수직 배치 제한
경로 찾기 계산은 특정 垂直 경계 내의 부품만 고려합니다:
- 하한 경계 — 하단 Y 좌표가 -65,536스터드 미만인 부품은 무시됩니다.
- 상한 경계 — 상위 Y 좌표를 가진 부품이 65,536스터드를 초과하면 무시됩니다.
- 수직 스팬 — 가장 낮은 부분의 하단 Y 좌표에서 가장 높은 부분의 상단 Y 좌표까지의 수직 거리는 65,536스터드를 초과해서는 안되며, 그렇지 않으면 경로 찾기 시스템이 그 부분을 경로 찾기 계산 중에 무시합니다.
검색 거리 제한
시작 지점에서 종료 지점까지의 직선 시야 거리는 3,000스터드를 초과해서는 안됩니다.이 거리를 초과하면 NoPath 상태가 발생합니다.
경로 생성
경로 찾기는 PathfindingService 및 해당 CreatePath() 함수를 통해 시작됩니다.
로컬 스크립트
local PathfindingService = game:GetService("PathfindingService")local path = PathfindingService:CreatePath()
CreatePath()는 문자(에이전트)가 경로를 따라 이동하는 방식을 미세 조정하는 선택적 매개변수 테이블을 수락합니다.
키 | 설명 | 유형 | 기본 |
---|---|---|---|
AgentRadius | Agent 반경, 스터드 단위. 장애물로부터의 최소 분리를 결정하는 데 유용합니다. | 정수 integer | 2 |
AgentHeight | 에이전트 높이, 스터드 단위. 계단 아래의 공간과 같이 이 값보다 작은 빈 공간은 통과할 수 없는 것으로 표시됩니다. | 정수 integer | 5 |
AgentCanJump | 경로 찾기 중에 점프가 허용되는지 여부를 결정합니다. | 부울 | true |
AgentCanClimb | 경로 찾기 중에 등반 TrussParts 이 허용되는지 여부를 결정합니다. | 부울 | false |
WaypointSpacing | 경로에서 중간 웨이포인트 사이의 간격. math.huge로 설정하면 중간 웨이포인트가 없습니다. | 번호 | 4 |
Costs | 재료 테이블 또는 정의된 PathfindingModifiers 및 검색에 대한 비용.에이전트가 다른 것보다 특정 재료/지역을 선호하도록 만드는 데 유용합니다.자세한 내용은 모디파이어를 참조하십시오. | 테이블 | nil |
로컬 스크립트
local PathfindingService = game:GetService("PathfindingService")local path = PathfindingService:CreatePath({AgentRadius = 3,AgentHeight = 6,AgentCanJump = false,Costs = {Water = 20}})
에이전트는 경로 탐색 중에 동안 올라갈 수 있으며, 경로를 생성할 때 를 으로 설정하고 트러스 등반 경로에서 에이전트를 차단하는 것이 없다고 가정합니다.등반할 수 있는 경로에는 등반 레이블과 비용이 있으며, 등반할 수 있는 경로의 비용은 기본적으로 1 이다.

로컬스크립트 - 트러스 등반 경로
local PathfindingService = game:GetService("PathfindingService")local path = PathfindingService:CreatePath({AgentCanClimb = true,Costs = {Climb = 2 -- 등반 경로 비용; 기본값은 1입니다}})
경로를 따라 이동
이 섹션에서는 플레이어의 캐릭터에 대해 다음 경로 찾기 스크립트를 사용합니다. 읽으면서 테스트하려면:
- 코드를 LocalScript 내에 StarterCharacterScripts 에 복사하십시오.
- 플레이어 캐릭터가 도달할 수 있는 3D 세계의 TEST_DESTINATION``Datatype.Vector3 설정하십시오.
- 경로 계산과 문자 이동에 대해 알아보려면 다음 섹션을 계속 진행하십시오.
로컬스크립트 - 문자 경로 찾기
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local path = PathfindingService:CreatePath()
local player = Players.LocalPlayer
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
local TEST_DESTINATION = Vector3.new(100, 0, 100)
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local function followPath(destination)
-- 경로 계산
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
-- 경로 지점 가져오기
waypoints = path:GetWaypoints()
-- 경로가 차단되는지 여부 감지
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
-- 장애물이 경로 아래에 있는지 확인하십시오
if blockedWaypointIndex >= nextWaypointIndex then
-- 경로가 다시 계산될 때까지 경로 차단 감지 중지
blockedConnection:Disconnect()
-- 새로운 경로를 다시 계산하기 위해 함수 호출
followPath(destination)
end
end)
-- 다음 웨이포인트로의 이동이 완료되었는지 감지
if not reachedConnection then
reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
-- 경로 지점 인덱스 증가 및 다음 경로 지점으로 이동
nextWaypointIndex += 1
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
end
end)
end
-- 처음에 두 번째 웨이포인트로 이동(첫 번째 웨이포인트는 경로 시작; 건너뛰기)
nextWaypointIndex = 2
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn("Path not computed!", errorMessage)
end
end
followPath(TEST_DESTINATION)
경로 계산
를 사용하여 시작 지점과 목적지 모두에 대해 를 호출하여 유효한 경로를 만든 후에는 두 지점 모두에 대해 를 계산해야 합니다.
로컬스크립트 - 문자 경로 찾기
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local path = PathfindingService:CreatePath()
local player = Players.LocalPlayer
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
local TEST_DESTINATION = Vector3.new(100, 0, 100)
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local function followPath(destination)
-- 경로 계산
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
end

웨이포인트 받기
Path가 계산되면 시작부터 종료경로를 추적하는 일련의 웨이포인트 가 포함됩니다.이 포인트는 Path:GetWaypoints() 함수로 수집할 수 있습니다.
로컬스크립트 - 문자 경로 찾기
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local path = PathfindingService:CreatePath()
local player = Players.LocalPlayer
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
local TEST_DESTINATION = Vector3.new(100, 0, 100)
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local function followPath(destination)
-- 경로 계산
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
-- 경로 지점 가져오기
waypoints = path:GetWaypoints()
end
end

경로 이동
각 웨이포인트는 위치 ()와 작업 ()이 모두 포함됩니다.일반적인 Roblox 캐릭터와 같이 캐릭터에 Humanoid 를 이동하려면 방법점에서 방법점으로 Humanoid:MoveTo() 를 호출하여 캐릭터가 각 방법점에 도달했을 때 검색할 MoveToFinished 이벤트를 사용하여 가장 쉬운 방법입니다.
로컬스크립트 - 문자 경로 찾기
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local path = PathfindingService:CreatePath()
local player = Players.LocalPlayer
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
local TEST_DESTINATION = Vector3.new(100, 0, 100)
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local function followPath(destination)
-- 경로 계산
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
-- 경로 지점 가져오기
waypoints = path:GetWaypoints()
-- 경로가 차단되는지 여부 감지
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
-- 장애물이 경로 아래에 있는지 확인하십시오
if blockedWaypointIndex >= nextWaypointIndex then
-- 경로가 다시 계산될 때까지 경로 차단 감지 중지
blockedConnection:Disconnect()
-- 새로운 경로를 다시 계산하기 위해 함수 호출
followPath(destination)
end
end)
-- 다음 웨이포인트로의 이동이 완료되었는지 감지
if not reachedConnection then
reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
-- 경로 지점 인덱스 증가 및 다음 경로 지점으로 이동
nextWaypointIndex += 1
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
end
end)
end
-- 처음에 두 번째 웨이포인트로 이동(첫 번째 웨이포인트는 경로 시작; 건너뛰기)
nextWaypointIndex = 2
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn("Path not computed!", errorMessage)
end
end
차단된 경로 처리
많은 Roblox 세계가 동적이며, 부품이 이동하거나 떨어지고 바닥이 무너질 수 있습니다.이렇게 하면 계산된 경로가 차단되고 문자가 목적지에 도달하지 못할 수 있습니다.이를 처리하려면 Path.Blocked 이벤트를 연결하고 차단한 것의 주위의 경로를 다시 계산할 수 있습니다.
로컬스크립트 - 문자 경로 찾기
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local path = PathfindingService:CreatePath()
local player = Players.LocalPlayer
local character = player.Character
local humanoid = character:WaitForChild("Humanoid")
local TEST_DESTINATION = Vector3.new(100, 0, 100)
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local function followPath(destination)
-- 경로 계산
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
-- 경로 지점 가져오기
waypoints = path:GetWaypoints()
-- 경로가 차단되는지 여부 감지
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
-- 장애물이 경로 아래에 있는지 확인하십시오
if blockedWaypointIndex >= nextWaypointIndex then
-- 경로가 다시 계산될 때까지 경로 차단 감지 중지
blockedConnection:Disconnect()
-- 새로운 경로를 다시 계산하기 위해 함수 호출
followPath(destination)
end
end)
end
end
경로 찾기 수정자
기본적으로, 는 시작 지점과 목적지 사이의 가장 짧은 경로를 반환하지만, 점프를 피하려고 시도합니다.이는 일부 상황에서 자연스럽지 않아 보입니다. 예를 인스턴스, 물을 통해 경로가 지나갈 수 있으며, 물을 통한 경로가 기하학적으로 더 짧기 때문입니다.

경로 찾기를 최적화하려면 경로 찾기 수정자 를 구현하여 다양한 재료, 주어진 지역, 또는 장애물을 통해 더 똑똑한 경로를 계산할 수 있습니다.
재료 비용 설정
Terrain 및 BasePart 재료로 작업할 때, 특정 재료를 다른 재료보다 더 가로지르게 만들기 위해 Costs 테이블을 CreatePath() 내에 포함할 수 있습니다.모든 재료에는 기본 비용이 1이고 모든 재료는 값을 으로 설정하여 트래버스할 수 없는 것으로 정의될 수 있습니다.
Costs 테이블의 키는 예를 들어 Enum.Material 이름을 나타내는 문자열 이름이어야 합니다, 예를 들어 Water 에 대한 Enum.Material.Water.
로컬스크립트 - 문자 경로 찾기
local PathfindingService = game:GetService("PathfindingService")local Players = game:GetService("Players")local RunService = game:GetService("RunService")local Workspace = game:GetService("Workspace")local path = PathfindingService:CreatePath({Costs = {Water = 20,Mud = 5,Neon = math.huge}})
지역 작업
일부 경우, 재료 선호도가 충분하지 않습니다.예를 들어, 캐릭터가 발 아래의 재료에 관계없이 정의된 영역을 피하기를 원할 수 있습니다. 부품에 PathfindingModifier 개체를 추가하여 이를 달성할 수 있습니다.
위험한 지역 주위에 Anchored 부품을 만들고 해당 CanCollide 속성을 false 로 설정합니다.
부품에 PathfindingModifier 인스턴스를 삽입하고, 해당 Label 속성을 찾아 의미 있는 이름, 예를 들어 DangerZone 을 할당합니다.
일치하는 키와 관련된 숫자 값이 포함된 Costs 테이블을 CreatePath() 내에 포함하십시오.변형자는 값을 math.huge로 설정하여 트래버스할 수 없는 것으로 정의할 수 있습니다.
로컬스크립트 - 문자 경로 찾기local PathfindingService = game:GetService("PathfindingService")local Players = game:GetService("Players")local RunService = game:GetService("RunService")local Workspace = game:GetService("Workspace")local path = PathfindingService:CreatePath({Costs = {DangerZone = math.huge}})
장애물 무시
경우에 따라 존재하지 않는 것처럼 단단한 장애물을 통해 길을 찾는 것이 유용합니다.이렇게 하면 특정 물리적 차단기를 통해 경로를 계산할 수 있으므로 계산이 실패하는 것보다 낫습니다.
개체 주위에 Anchored 부품을 만들고 해당 CanCollide 속성을 false 로 설정합니다.
부품에 PathfindingModifier 인스턴스를 삽입하고 PassThrough 속성을 활성화합니다.
이제 좀비 NPC에서 플레이어 캐릭터로 경로가 계산될 때 경로는 문 너머로 확장되며 좀비에게 경로를 통과하도록 요청할 수 있습니다.좀비가 문을 열 수 없더라도 문 뒤에 있는 캐릭터를 "들은 것"처럼 반응합니다.
경로 찾기 링크
때때로 협곡과 같이 일반적으로 통과할 수 없는 공간에서 경로를 찾아 다음 웨이포인트에 도달하기 위한 사용자 지정 작업을 수행해야 합니다.이는 PathfindingLink 개체를 통해 달성할 수 있습니다.
위의 섬 예제를 사용하여 에이전트가 모든 다리를 걸어 건너는 대신 보트를 사용하도록 만들 수 있습니다.

이 예제를 사용하여 PathfindingLink를 생성하려면:
시각화 및 디버깅을 지원하기 위해, 3D 뷰포트의 오른쪽 상단에 있는 시각화 옵션 위젯에서 경로 찾기 링크를 토글합니다.
보트의 좌석과 보트 착륙 지점 근처에 두 개의 Attachments를 만듭니다.
의미 있는 이름, 예를 들어 UseBoat 을 해당 Label 속성에 할당합니다.이 이름은 경로 찾기 스크립트에서 플래그로 사용되어 에이전트가 시작 링크 지점에 도달할 때 사용자 지정 작업을 트리거합니다.
두 개의 키와 속성 이름에 일치하는 사용자 지정 키가 포함된 테이블을 포함하여 속성 이름에 맞는 테이블을 포함하십시오.사용자 지정 키에 값 Water 보다 낮은 값을 할당합니다.
로컬스크립트 - 문자 경로 찾기local PathfindingService = game:GetService("PathfindingService")local Players = game:GetService("Players")local RunService = game:GetService("RunService")local Workspace = game:GetService("Workspace")local path = PathfindingService:CreatePath({Costs = {Water = 20,UseBoat = 1}})경로 지점에 도달할 때 발생하는 이벤트에서 모디파이어 이름에 대한 사용자 지정 검사를 추가하고 다른 행동을 수행합니다. 이 경우, 함수를 호출하여 에이전트를 보트에 앉히고, 물을 가로지르고 목적지에 도착하면 에이전트의 경로를 계속하는 것입니다.
로컬스크립트 - 문자 경로 찾기local PathfindingService = game:GetService("PathfindingService")local Players = game:GetService("Players")local RunService = game:GetService("RunService")local Workspace = game:GetService("Workspace")local path = PathfindingService:CreatePath({Costs = {Water = 20,UseBoat = 1}})local player = Players.LocalPlayerlocal character = player.Characterlocal humanoid = character:WaitForChild("Humanoid")local TEST_DESTINATION = Vector3.new(228.9, 17.8, 292.5)local waypointslocal nextWaypointIndexlocal reachedConnectionlocal blockedConnectionlocal function followPath(destination)-- 경로 계산local success, errorMessage = pcall(function()path:ComputeAsync(character.PrimaryPart.Position, destination)end)if success and path.Status == Enum.PathStatus.Success then-- 경로 지점 가져오기waypoints = path:GetWaypoints()-- 경로가 차단되는지 여부 감지blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)-- 장애물이 경로 아래에 있는지 확인하십시오if blockedWaypointIndex >= nextWaypointIndex then-- 경로가 다시 계산될 때까지 경로 차단 감지 중지blockedConnection:Disconnect()-- 새로운 경로를 다시 계산하기 위해 함수 호출followPath(destination)endend)-- 다음 웨이포인트로의 이동이 완료되었는지 감지if not reachedConnection thenreachedConnection = humanoid.MoveToFinished:Connect(function(reached)if reached and nextWaypointIndex < #waypoints then-- 경로 지점 인덱스 증가 및 다음 경로 지점으로 이동nextWaypointIndex += 1-- 웨이포인트 레이블이 "UseBoat"인 경우 보트를 사용하고, 그렇지 않으면 다음 웨이포인트로 이동합니다if waypoints[nextWaypointIndex].Label == "UseBoat" thenuseBoat()elsehumanoid:MoveTo(waypoints[nextWaypointIndex].Position)endelsereachedConnection:Disconnect()blockedConnection:Disconnect()endend)end-- 처음에 두 번째 웨이포인트로 이동(첫 번째 웨이포인트는 경로 시작; 건너뛰기)nextWaypointIndex = 2humanoid:MoveTo(waypoints[nextWaypointIndex].Position)elsewarn("Path not computed!", errorMessage)endendfunction useBoat()local boat = Workspace.BoatModelhumanoid.Seated:Connect(function()-- 에이전트가 앉아 있으면 보트 이동 시작if humanoid.Sit thentask.wait(1)boat.CylindricalConstraint.Velocity = 5end-- 섬과 관련된 제약 조건 위치 감지local boatPositionConnectionboatPositionConnection = RunService.PostSimulation:Connect(function()-- 섬 옆에서 보트 멈추기if boat.CylindricalConstraint.CurrentPosition >= 94 thenboatPositionConnection:Disconnect()boat.CylindricalConstraint.Velocity = 0task.wait(1)-- 에이전트 제거 및 목적지 계속humanoid.Sit = falsehumanoid:MoveTo(waypoints[nextWaypointIndex].Position)endend)end)endfollowPath(TEST_DESTINATION)
스트리밍 호환성
경험 내 인스턴스 스트리밍은 플레이어의 캐릭터가 세계 주변을 이동하는 동안 3D 콘텐츠를 동적으로 로드하고 언로드하는 강력한 기능입니다.3D 공간을 탐색하면서 공간 스트림의 새로운 하위 집합이 장치에 스트림되고 기존 하위 집합 중 일부가 스트림될 수 있습니다.
스트리밍 활성화 경험에서 PathfindingService를 사용하기 위한 다음 모범 사례를 고려하십시오:
스트리밍은 특정 경로를 이동하는 동안 차단하거나 차단을 해제할 수 있습니다.예를 들어, 캐릭터가 숲을 통과하는 동안 나무가 앞서서 스트림을 방해하고 경로를 차단할 수 있습니다.스트리밍과 함께 경로 찾기 작업을 원활하게 수행하려면 처리 차단된 경로 기술을 사용하고 필요할 때 경로를 다시 계산하는 것이 좋습니다.
경로 찾기에서 공통적으로 사용되는 방법은 세계에서 기존 보물 상자 모델의 위치로 경로 목적지를 설정하는 것과 같이 기존 개체의 좌표를 사용하여 계산 하는 것입니다.이 접근법은 서버가 항상 세계의 전체 뷰를 가지고 있기 때문에 서버 측과 완전히 호환되며, Scripts 클라이언트에서 실행되는 LocalScripts 및 ModuleScripts 는 입력되지 않는 개체로 가는 경로를 계산하려고 시도하면 실패할 수 있습니다.
이 문제를 해결하려면 영구 모델 내에서 의 위치에 대상을 설정하는 것을 고려하십시오.지속적 모델은 플레이어가 참여한 후 곧 로드되며 결코 스트리밍되지 않으므로 클라이언트 스크립트가 이벤트가 발생한 후 방향점을 생성하기 위해 모델에 안전하게 액세스할 수 있습니다.