การค้นหาเส้นทาง เป็นกระบวนการย้ายตัวละครไปตามเส้นทางโลจิสติกที่จะไปถึงจุดหมายโดยหลีกเลี่ยงอุปสรรคและ (ตัวเลือก) วัสดุอันตรายหรือพื้นที่ที่กำหนด
การแสดงภาพการนําทาง
เพื่อช่วยในการค้นหาเส้นทางและการดีบัก Studio สามารถเรนเดอร์เมชและแท็บปรับแต่ง modifierเพื่อเปิดใช้งานพวกเขาให้สลับเปิด เนวิเกชันเมช และ ตัวปรับเส้นทาง จากแท็บ ตัวเลือกการแสดงผล ในมุมขวาบนของหน้าต่าง 3D วิวพอร์ต

เมื่อเปิดใช้งานเมช เครือข่ายการนําทาง แล้ว พื้นที่สีสันจะแสดงตำแหน่งที่ตัวละครอาจเดินหรือว่ายน้ำ ในขณะที่พื้นที่สีไม่สันจะถูกบล็อกลูกศรขนาดเล็กบ่งบอกถึงพื้นที่ที่ตัวละครจะพยายามไปถึงโดยการกระโดดโดยสมมติว่าคุณตั้ง AgentCanJump เป็น true เมื่อ สร้างเส้นทาง

เมื่อเปิดใช้งานตัวปรับเปลี่ยนการค้นหาเส้นทาง **** แล้ว ฉลากข้อความจะระบุวัสดุและภูมิภาคที่เฉพาะเจาะจงที่จะนำมาพิจารณาเมื่อใช้ตัวปรับเปลี่ยนการค้นหาเส้นทาง

ข้อจำกัดที่รู้จัก
คุณลักษณะการค้นหาเส้นทางมีข้อจํากัดเฉพาะเพื่อให้แน่ใจว่ามีการประมวลผลอย่างมีประสิทธิภาพและประสิทธิภาพสูงสุด
ขีดจํากัดการวางแนวตั้ง
การคำนวณการค้นหาเส้นทางพิจารณาเฉพาะส่วนภายในขอบเขตแนวตั้งที่กำหนดเท่านั้น:
- ขอบล่าง — ชิ้นส่วนที่มีพิกัดด้านล่าง 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 | รัศมีตัวแทน, ในสตัด มีประโยชน์สำหรับการกำหนดระยะการแยกขั้นต่ำจากอุปสรรค | จํานวนเต็ม | 2 |
AgentHeight | ความสูงของตัวแทนในสตัด พื้นที่ว่างที่เล็กกว่ามูลค่านี้, เช่นพื้นที่ใต้บันได, จะถูกบอกว่าไม่สามารถข้ามได้ | จํานวนเต็ม | 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}})
โปรดทราบว่าตัวแทนสามารถปีนได้ TrussParts ระหว่างการค้นหาเส้นทางโดยสมมติว่าคุณตั้ง AgentCanClimb เป็น true เมื่อ สร้างเส้นทาง และไม่มีอะไรบล็อกตัวแทนจากเส้นทางการปีนของเทรลล์เส้นทางที่ปีนได้มีป้าย ปีน และ ค่าใช้จ่าย สำหรับเส้นทางที่ปีนได้คือ 1 โดยปกติ

สคริปท้องถิ่น - เส้นทางปีนเขาแทรส
local PathfindingService = game:GetService("PathfindingService")local path = PathfindingService:CreatePath({AgentCanClimb = true,Costs = {Climb = 2 -- ค่าของเส้นทางการปีน; ค่าเริ่มต้นคือ 1}})
เคลื่อนทางไปตามเส้นทาง
ส่วนนี้ใช้สคริปต์ค้นหาเส้นทางต่อไปนี้สำหรับตัวละครของผู้เล่น เพื่อทดสอบขณะอ่าน:
- คัดลอกโค้ดลงใน LocalScript ภายใน StarterCharacterScripts
- ตั้งแปร ให้เป็นจุดหมายปลายทางในโลก 3D ที่ผู้เล่นตัวละครสามารถเข้าถึงได้
- ดำเนินการผ่านส่วนต่อไปเพื่อเรียนรู้เกี่ยวกับการคำนวณเส้นทางและการเคลื่อนที่ของตัวละคร
สคริปท้องถิ่น - การค้นหาเส้นทางตัวละคร
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)
คำนวณเส้นทาง
หลังจากที่คุณสร้างเส้นทางที่ถูกต้องด้วย CreatePath() คุณต้อง คำนวณ โดยเรียก Path:ComputeAsync() ด้วย 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)
end

รับเวย์พอยท์
เมื่อ Path ถูกคำนวณแล้ว มันจะมีซีรีส์ของ waypoints ปิด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

การเคลื่อนทางเส้นทาง
แต่ละเวย์พอยท์ประกอบด้วยทั้งตําแหน่ง ( ) และการกระทํา ( )เพื่อย้ายตัวละครที่มี Humanoid เช่นตัวละคร Roblox ทั่วไป วิธีที่ง่ายที่สุดคือการโทร 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 และวัสดุใดๆ สามารถกำหนดได้ว่าไม่สามารถข้ามได้โดยการตั้งค่ามูลค่าของมันเป็น math.huge
คีย์ในตาราง 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 เป็น ปิด
ใส่ตัวอย่าง 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 เป็น ปิด
ใส่ตัวอย่าง PathfindingModifier บนส่วนและเปิดใช้งานคุณสมบัติ PassThrough ของมัน
ตอนนี้เมื่อเส้นทางถูกคำนวณจาก NPC ซอมบี้ไปยังตัวละครผู้เล่นเส้นทางจะขยายไปเกินประตูและคุณสามารถส่งคำขอให้ซอมบี้เดินทางผ่านได้แม้ว่าซอมบี้จะไม่สามารถเปิดประตูได้ แต่มันจะตอบสนองเหมือนว่า "ได้ยิน" ตัวละครด้านหลังประตู
ลิงค์ค้นหาเส้นทาง
บางครั้งจำเป็นต้องหาเส้นทางข้ามพื้นที่ที่ไม่สามารถเดินทางได้ตามปกติ เช่น ข้ามหุบเขา และดำเนินการด้วยการกระทำที่กำหนดเองเพื่อไปถึงจุดหมายต่อไปสิ่งนี้สามารถทำได้ผ่านวัตถุ PathfindingLink
โดยใช้ตัวอย่างเกาะจากด้านบนคุณสามารถทำให้ตัวแทนใช้เรือแทนการเดินข้ามสะพานทั้งหมด

เพื่อสร้าง PathfindingLink โดยใช้ตัวอย่างนี้:
เพื่อช่วยในการวาดภาพและการแก้ไขข้อผิดพลาด เปิดใช้งาน ลิงก์ค้นหาเส้นทาง จากแดชบอร์ด ตัวเลือกการแสดงผล ในมุมบนขวาของหน้าต่าง 3D มุมมอง
สร้างสอง Attachments , หนึ่งบนที่นั่งเรือและหนึ่งใกล้จุดลงจอดของเรือ
สร้างวัตถุ PathfindingLink ในพื้นที่ทำงานจากนั้นกำหนดค่า แนบเนียน0 และ แนบเนียน1 คุณสมบัติให้กับแนบเนียนเริ่มต้นและสิ้นสุดตามลำดับ
กำหนดชื่อที่มีความหมายเช่น UseBoat ให้กับคุณสมบัติ Label ของมันชื่อนี้ใช้เป็นธงในสคริปต์การค้นหาเส้นทางเพื่อเรียกการดำเนินการที่กําหนดเองเมื่อตัวแทนถึงจุดเชื่อมต่อเริ่มต้น
รวมโต๊ะ Costs ภายใน CreatePath() ที่มีทั้งคีย์ Water และคีย์ที่กำหนดเองที่ตรงกับชื่อคุณสมบัติ 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}})ในอีเวนต์ที่จะยิงเมื่อถึงเวย์พอยท์ เพิ่มการตรวจสอบแบบกําหนดเองสําหรับชื่อตัวแก้ไข Label และดําเนินการต่างจาก Humanoid:MoveTo() ในกรณีนี้โดยเรียกฟังก์ชันเพื่อนั่งตัวแทนในเรือ, ย้ายเรือข้ามน้ํา, และดําเนินเส้นทางของตัวแทนต่อเมื่อมาถึงเกาะปลายทาง
สคริปท้องถิ่น - การค้นหาเส้นทางตัวละคร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-- ใช้เรือหากฉลากเส้นทางเป็น "ใช้เรือ"; มิฉะนั้นย้ายไปยังจุดหมายถัดไป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 ที่ทำงานบนไคลเอนต์อาจล้มเหลวหากพยายามคำนวณเส้นทางไปยังวัตถุที่ไม่ถูกสตรีมเข้ามา
เพื่อแก้ปัญหานี้ พิจารณาการตั้งเป้าหมายเป็นตำแหน่งของ BasePart ภายในรูปแบบ ถาวรโมเดลถาวรโหลดเร็วหลังจากที่ผู้เล่นเข้าร่วมและพวกเขาไม่เคยสตรีมออก ดังนั้นสคริปต์ด้านคลายสามารถเชื่อมต่อกับเหตุการณ์ PersistentLoaded และเข้าถึงโมเดลได้อย่างปลอดภัยเพื่อสร้างเวย์พอยท์หลังจากเหตุการณ์เกิดขึ้น