길 찾기 는 목적지에 도달하기 위해 논리적 경로를 따라 캐릭터를 이동하는 프로세스입니다. 장애물을 피하고 (선택적으로) 유해 물질 또는 정의된 영역을 피하도록 합니다.
탐색 시각화
경로 탐색 레이아웃 및 디버깅을 보조하기 위해 Studio는 탐색 메쉬 및 모디파이어 레이블을 렌더링할 수 있습니다. 활성화하려면 나비 메쉬 및 경로 찾기 모디파이어 레이블을 시각화 옵션 위젯에서
색상 영역을 활성화하면 색상 영역에서 캐릭터가 걸을 수 있는 곳이나 수영할 수 있는 곳을 표시하고, 색상 영역이 아닌 영역은 차단됩니다. 작은 화살표는 캐릭터가 점프하여 도달하려는 위치를 나타내고, 경로를 만들기 위해
길 찾기 모드리퍼를 활성화하면 길 찾기 모드리퍼를 사용할 때 고려하는 특정 재료 및 지역을 나타냅니다.
알려진 제한
경로 찾기 기능은 효율적인 처리와 최적인 이행보장하기 위해 특정 제한을 사용합니다.
직렬 배치 제한
경로 찾기 계산은 특정 垂直 경계 내의 부품만 고려합니다.
- 하단 경계 — Y 아래 좌표가 -65,536 보다 작은 부품은 무시됩니다.
- 상부 제한 - Y 좌표가 65,536개를 초과하는 부품은 무시됩니다.
- 垂直 스팬 — 가장 낮은 부분의 바닥에서 가장 높은 부분의 바닥까지의 垂直 거리 Y 값은 65,536 스터드를 초과해서는 안 됩니다; 그렇지 않으면 경로 찾기 시스템은 경로 찾기 계산 중에 해당 부품을 무시합니다.
검색 거리 제한
경로 찾기에서 시작점에서 끝점까지의 직접 시야 거리는 3,000 스터드를 초과해서는 안 됩니다. 이 거리를 초과하면 NoPath 상태가 됩니다.
경로 생성
경로 찾기는 PathfindingService 및 그 CreatePath() 함수를 통해 시작됩니다.
로컬 스크립트
local PathfindingService = game:GetService("PathfindingService")local path = PathfindingService:CreatePath()
CreatePath() 은 캐릭터(에이전트)가 경로를 따라 이동하는 방법을 미세 조정하는 옵션 테이블의 매개 변수를 수락합니다.
키 | 설명 | 유형 | 기본 |
---|---|---|---|
AgentRadius | 에이전트 라디오스, 스터드 단위. 장애물과의 최소 거리를 결정하는 데 유용합니다. | 정수 | 2 |
AgentHeight | 에이전트 높이, 스터드 단위입니다. 이 값보다 작은 공간은 계단 아래와 같이 횡단할 수 없음을 나타냅니다. | 정수 | 5 |
AgentCanJump | 경로 탐색 중에 점프할 수 있는지 여부를 결정합니다. | 부울 | true |
AgentCanClimb | 경로 탐색 중에 TrussParts 을 올라갈 수 있는지 여부를 결정합니다. | 부울 | false |
WaypointSpacing | 경로의 중간 지점 사이에 공간을 남깁니다. if set to math.huge , there will be no intermediate waypoints. | 숫자 | 4 |
Costs | 재료 테이블 또는 정의된 PathfindingModifiers 및 이동에 대한 비용. 특정 재료/지역을 다른 재료/지역보다 선호하게 하려면 modifiers를 참조하십시오. 세부 내용은 변경자를 참조하십시오. | 테이블 | nil |
로컬 스크립트
local PathfindingService = game:GetService("PathfindingService")local path = PathfindingService:CreatePath({AgentRadius = 3,AgentHeight = 6,AgentCanJump = false,Costs = {Water = 20}})
경로 탐색 시 에이전트가 TrussParts 을 올라갈 수 있지만, 경로 생성 시 AgentCanClimb 를 true 로 설정하면 트러스 클라이
로컬 스크립트 - 트러스 등반 경로
local PathfindingService = game:GetService("PathfindingService")local path = PathfindingService:CreatePath({AgentCanClimb = true,Costs = {Climb = 2 -- 올라가는 경로의 비용; 기본값은 1입니다.}})
길을 따라 이동
이 섹션에서는 플레이어의 캐릭터를 위해 다음 경로 찾기 스크립트를 사용합니다. 테스트 중에 읽기 위해:
- 코드를 LocalScript 내의 StarterCharacterScripts에 복사합니다.
- 플레이어 캐릭터가 도달할 수 있는 Vector3 대상으로 줄 11을 편집합니다.
- 다음 섹션을 통해 경로 계산 및 캐릭터 이동에 대해 알아보세요.
로컬 스크립트 - 캐릭터 경로 찾기
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
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)
경로 계산
After you've created a valid path with CreatePath() , it must be compute by calling Path:ComputeAsync() with a 1> Datatype.Vector31> for both the starting point and destination.
로컬 스크립트 - 캐릭터 경로 찾기
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
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
웨이포인트 얻기
Class.Path 가 계산되면 시작부터 종료경로를 추적하는 여러 개의 방향 이 포함됩니다. 이 방향은 Path:GetWaypoints() 함수로 수집할 수 있습니다.
로컬 스크립트 - 캐릭터 경로 찾기
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
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
경로 이동
각 웨이포인트는 위치 ( Vector3 )와 액션 ( 1> Class.PathWaypointAction|PathWaypoint
로컬 스크립트 - 캐릭터 경로 찾기
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
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 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
경로 찾기 모드리퍼
기본적으로, Path:ComputeAsync() 는 시작 지점과 목적지 사이의 가장 짧은 경로를 반환하지만, 피하기 위해 점프하지 않는 경우에는 그렇지 않습니다. 이 작동은 일부 상황에서 비정상적인 수준으로 나타납니다. 예를 인스턴스, 길이가 지정된 경로를 건너
경로 찾기를 더 최적화하려면 경로 찾기 모드를 구현하여 다양한 재료 , 주위의 영역 또는 장애물을 통해 더 스마트한 경로를 계산하십시오.
재료 비용 설정
Class.Terrain 및 BasePart 재료를 사용할 때 Costs 테이블을 1>Class.PathfindingService:CreatePath()|CreatePath()1> 에 포함하여 특정 재료를 더 횡
Costs 테이블에 있는 열은 이름을 나타내는 문자열 이어야 하며, 예를 들어 Enum.Material 대신 Water 입니다.
로컬 스크립트 - 캐릭터 경로 찾기
local PathfindingService = game:GetService("PathfindingService")local Players = game:GetService("Players")local RunService = game:GetService("RunService")local path = PathfindingService:CreatePath({Costs = {Water = 20,Mud = 5,Neon = math.huge}})
지역 작업
In some cases, 재료 선호 는 충분하지 않습니다. 예를 들어, 정의된 영역 을 피하려는 캐릭터가 있다면 이 작업을 수행하기 위해 부품에 PathfindingModifier 개체를 추가하는 것이 좋습니다. 이 작업은 1>재료 선호1> 개체를 부품에 추가하는 것으로
위험한 지역 주위에 위험한 구역 파트를 생성하고 Anchored 속성을 CanCollide으로 설정합니다.
부품에 PathfindingModifier 인스턴스를 삽입하고, 속성 Label 를 찾아내고, DangerZone 와 같은 의미 있는 이름을 할당하십시오.
Class.PathfindingService:CreatePath()|CreatePath() 내에 일치하는 키와 관련된 숫자 값을 포함하는 Costs 테이블을 含하는 테이블을 含하는 경우 모드 수정자를 Library.math.huge 로 정의할 수 있습니다.
로컬 스크립트 - 캐릭터 경로 찾기local PathfindingService = game:GetService("PathfindingService")local Players = game:GetService("Players")local RunService = game:GetService("RunService")local path = PathfindingService:CreatePath({Costs = {DangerZone = math.huge}})
장애물 무시
일부 경우 경로 찾기는 실제 블록이 없는 것처럼 고체 장애물을 통과하는 것이 유용합니다. 이를 통해 특정 물리적 블록을 계산하는 대신 전체 계산을 실패하지 않고 계산할 수 있습니다.
개체 주위에 Anchored 부품을 생성하고 속성 CanCollide 를 거짓으로 설정합니다.
부품에 PathfindingModifier 인스턴스를 삽입하고 속성 PassThrough 를 활성화합니다.
이제 좀비 덩어리에서 플레이어 캐릭터로 경로를 계산할 때 경로가 문을 넘어가므로 좀비가 문을 열 수 없더라도 좀비가 문 뒤에 있는 캐릭터를 트래버스할 수 있습니다. 좀비가 문을 열 수 없더라도 좀비가 문 뒤에 있는 캐릭터를 트래버스할 수 있습니다.
경로 찾기 링크
때로는 정상적으로 여행할 수 없는 공간의 경로를 찾는 것이 필요합니다, 예를 들어 절벽 너머로, 다음 방향 포인트에 도달하기 위해 사용자 정의 된 작업을 수행하는 것입니다. 이 작업은 PathfindingLink 개체를 통해 수행 할 수 있습니다.
위의 섬 예시를 사용하면 에이전트가 다리 전체를 걸어 다니는 대신 보트를 사용할 수 있습니다.
이 예를 사용하여 PathfindingLink를 생성하려면:
시각화 및 디버깅을 보조하기 위해, 3D 뷰포트의 왼쪽 상단 모서리에 있는 경로 찾기 링크 를 시각화 옵션 위젯에서 토글하십시오.
보트 의자 하나 및 보트 착륙점 근처에 하나의 Attachments 을 생성합니다.
작업 공간에서 PathfindingLink 개체를 생성한 다음 시작 및 종료 부착물에 각각 Attachment0 및 Attachment1 속성을 할당합니다.
보트 이름과 같은 의미 있는 이름을 UseBoat 속성에 할당하십시오. 이 이름은 경로 찾기 스크립트에서 플래그로 사용되어 경로 찾기 스크립트에서 사용자가 시작 링크 지점에 도착할 때 사용자 지정 동작을 트리거합니다.
In include a Costs table within CreatePath() containing both a Water key and a custom key matching the 1> Class.PathfindingLink.Label|Label1> property name. Assign the custom key a lower value than 4> Water4> .
로컬 스크립트 - 캐릭터 경로 찾기local PathfindingService = game:GetService("PathfindingService")local Players = game:GetService("Players")local RunService = game:GetService("RunService")local path = PathfindingService:CreatePath({Costs = {Water = 20,UseBoat = 1}})방향점이 도착하는 이벤트에서 Label 모듈러 이름에 대한 사용자 지정 검사를 추가하고 Humanoid:MoveTo() 를 호출하여 에이전트를 보트에 앉게 하고, 보트를 물 위로 이동하고, 목적지 섬에
로컬 스크립트 - 캐릭터 경로 찾기local PathfindingService = game:GetService("PathfindingService")local Players = game:GetService("Players")local RunService = game:GetService("RunService")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)
스트리밍 호환성
In-experience 인스턴스 스트리밍 은 플레이어 캐릭터가 전 세계를 돌아 다니는 동안 3D 콘텐츠를 동적으로 로드하고 로드하지 않는 강력한 기능입니다. 3D 공간을 탐색하는 동안 새로운 3D 하위 집합을 장치에 스트림하고 일부 기존 하위 집합을 스트림하면 일부 하위
스트리밍 사용 가능한 경험에서 PathfindingService를 사용하는 다음 모범 사례를 고려하십시오.
스트리밍은 캐릭터가 길을 따라 이동하는 동안 주어진 경로를 블록하거나 블록할 수 있습니다. 예를 들어, 캐릭터가 숲을 통과하는 동안 나무가 어딘가에서 스트림하고 길을 방해하면 경로를 원활하게 처리하기 위해 필요할 수 있는 처리 차단된
경로 찾기에서 일반적인 접근 방식은 세계의 모든 위치에 있는 현재 보물 상자 모델의 위치를 설정하는 것과 같은 <
이 문제를 해결하려면 지속 모델 내의 BasePart 위치를 설정하여 대상을 지속 모델 내에 유지하십시오. 지속 모델은 플레이어가 합류하면 즉시 로드되고 결코 스트림되지 않므로 클라이언트 사이 스크립트를 연결하여