Wegfindung ist der Prozess, einen Charakter entlang eines logischen Weges zu bewegen, um ein Ziel zu erreichen, Hindernisse zu vermeiden und (optional) gefährliche Materialien oder definierte Regionen zu vermeiden.
Navigationsvisualisierung
Um beim Pfadfindungslayout und der Fehlersuche zu helfen, kann Studio eine Navigationsmeshes und Modifizierungslabels rendern.Um sie zu aktivieren, schalte auf Navigationsmeshes und Wegfindungsmodifizierer von der Visualisierungsoptionen-Widget in der oberen rechten Ecke des 3D-Ansichtsfensters um.

Mit Navigationsmeshes aktiviert zeigen farbige Bereiche an, wo ein Charakter gehen oder schwimmen könnte, während nicht farbige Bereiche blockiert sind.Die kleinen Pfeile zeigen Bereiche an, die ein Charakter durch Springen erreichen wird, unter der Annahme, dass du AgentCanJump auf true festlegst, wenn du den Weg erstellst.

Mit Wegfindungsmodifizierern aktiviert zeigen Text-Etiketten spezifische Materialien und Regionen an, die bei der Verwendung von Wegfindungsmodifizierern berücksichtigt werden.

Bekannte Einschränkungen
Wegfindungsfunktionen haben spezifische Einschränkungen, um effiziente Verarbeitung und optimale Erfüllungzu gewährleisten.
Vertikale Platzierungsgrenze
Wegfindungsrechnungen betrachten nur Teile innerhalb bestimmter vertikaler Grenzen:
- Untergrenze — Teile mit einer unteren Y -Koordinate von weniger als -65,536 Klötzen werden ignoriert.
- Obergrenze — Teile mit einer Spitzenkoordinate von Y , die 65.536 Klötze überschreiten, werden ignoriert.
- Vertikale Spannweite — Die vertikale Entfernung von der Unterseite des niedrigsten Teils Y Koordinate bis zur Oberseite des höchsten Teils Y Koordinate darf nicht mehr als 65.536 Klötze betragen; sonst wird das Wegfindungs-System diese Teile während der Wegfindungsrechnung ignorieren.
Such距離限制 Einschränkung
Die direkte Sichtweiterentfernung für den Wegfindungsprozess vom Startpunkt zum Zielpunkt darf nicht mehr als 3.000 Stollen betragen.Die Überschreitung dieser Entfernung führt zu einem NoPath Status.
Wege erstellen
Wegfindung wird durch PathfindingService und seine CreatePath() Funktion initiiert.
Lokales Skript
local PathfindingService = game:GetService("PathfindingService")local path = PathfindingService:CreatePath()
CreatePath() akzeptiert eine optionale tabelle von parametern, die das bewegen des charakters (agenten) entlang des weges feinabstimmt.
Schlave | Beschreibung | Typ | Standardmäßig |
---|---|---|---|
AgentRadius | Agentenradius, in Studs. Nützlich für die Bestimmung der Mindesttrennung von Hindernissen. | ganzzahlig | 2 |
AgentHeight | Agentenhöhe, in Studs. Leerer Raum kleiner als dieser Wert, wie der Raum unter den Treppen, wird als nicht durchdringbar markiert. | ganzzahlig | 5 |
AgentCanJump | Bestimmt, ob das Springen während des Wegfindungsprozesses erlaubt ist. | boolesisch | true |
AgentCanClimb | Bestimmt, ob das Klettern TrussParts während des Wegfindungsprozesses erlaubt ist. | boolesisch | false |
WaypointSpacing | Abstand zwischen Zwischenhaltestellen im Weg. Wenn er auf math.huge gesetzt ist, gibt es keine Zwischenhaltestellen. | zahl | 4 |
Costs | Tabelle der Materialien oder definierte PathfindingModifiers und ihre Kosten für die Durchquerung.Nützlich, um den Agenten bestimmte Materialien/Regionen vorzuziehen gegenüber anderen.Siehe Modifizierer für Details. | tabelle | nil |
Lokales Skript
local PathfindingService = game:GetService("PathfindingService")local path = PathfindingService:CreatePath({AgentRadius = 3,AgentHeight = 6,AgentCanJump = false,Costs = {Water = 20}})
Beachten Sie, dass der Agent während des Wegfindungsprozesses TrussParts klettern kann, wenn Sie AgentCanClimb auf true festlegen, wenn der Weg erstellt wird und nichts den Agenten vom Truss-Kletterweg blockiert.Ein kletterbarer Weg hat das Label Klettern und die Kosten für einen kletterbaren Weg betragen standardmäßig 1 .

LocalScript - Pfad
local PathfindingService = game:GetService("PathfindingService")local path = PathfindingService:CreatePath({AgentCanClimb = true,Costs = {Climb = 2 -- Kosten des Kletterwegs; Standard ist 1}})
Entlang von Pfaden bewegen
Dieser Abschnitt verwendet das folgende Suchskript für den Charakter des Spieler:in. Um während des Lesens zu testen:
- Kopiere den Code in ein LocalScript innerhalb von StarterCharacterScripts.
- Setze die TEST_DESTINATION Variable auf eine Vector3 Ziel destination in deiner 3D-Welt, die der Spielercharakter erreichen kann.
- Gehen Sie durch die folgenden Abschnitte, um mehr über den Wegrechnung und die Charakterbewegung zu erfahren.
LocalScript - Charakter-Pfadfindung
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)
-- Den Weg berechnen
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
-- Holen Sie sich die Wegpunkte
waypoints = path:GetWaypoints()
-- Erkennen, ob der Weg blockiert wird
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
-- Überprüfe, ob das Hindernis weiter auf dem Weg ist
if blockedWaypointIndex >= nextWaypointIndex then
-- Hör auf, den Wegblock zu erkennen, bis der Weg neu berechnet wird
blockedConnection:Disconnect()
-- Funktion aufrufen, um einen neuen Weg erneut zu berechnen
followPath(destination)
end
end)
-- Erkennen, wenn die Bewegung zum nächsten Wegpunkt abgeschlossen ist
if not reachedConnection then
reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
-- Erhöhe den Wegpunkt-Index und bewege dich zum nächsten Wegpunkt
nextWaypointIndex += 1
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
end
end)
end
-- Bewegen Sie sich zunächst zum zweiten Wegpunkt (der erste Wegpunkt ist der starten; überspringen Sie ihn)
nextWaypointIndex = 2
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn("Path not computed!", errorMessage)
end
end
followPath(TEST_DESTINATION)
Den Weg berechnen
Nachdem du einen gültigen Pfad mit CreatePath() erstellt hast, muss er berechnet werden , indem du Path:ComputeAsync() mit einem Vector3 für den Startpunkt und den Zielpunkt aufrufst.
LocalScript - Charakter-Pfadfindung
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)
-- Den Weg berechnen
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
end

Wegpunkte erhalten
Sobald die Path berechnet wurde, enthält sie eine Reihe von Wegpunkten , die den Weg von Anfang bis beendenverfolgen.Diese Punkte können mit der Path:GetWaypoints()-Funktion gesammelt werden.
LocalScript - Charakter-Pfadfindung
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)
-- Den Weg berechnen
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
-- Holen Sie sich die Wegpunkte
waypoints = path:GetWaypoints()
end
end

Wegbewegung
Jeder Wegpunkt besteht aus einer Position () und einer Aktion ().Um einen Charakter zu verschieben, der einen Humanoid enthält, wie ein typischer Roblox-Charakter, ist der einfachste Weg, Humanoid:MoveTo() von Wegpunkt zu Wegpunkt zu rufen, und verwenden Sie das Ereignis MoveToFinished, um zu erkennen, wann der Charakter jeden Wegpunkt erreicht.
LocalScript - Charakter-Pfadfindung
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)
-- Den Weg berechnen
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
-- Holen Sie sich die Wegpunkte
waypoints = path:GetWaypoints()
-- Erkennen, ob der Weg blockiert wird
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
-- Überprüfe, ob das Hindernis weiter auf dem Weg ist
if blockedWaypointIndex >= nextWaypointIndex then
-- Hör auf, den Wegblock zu erkennen, bis der Weg neu berechnet wird
blockedConnection:Disconnect()
-- Funktion aufrufen, um einen neuen Weg erneut zu berechnen
followPath(destination)
end
end)
-- Erkennen, wenn die Bewegung zum nächsten Wegpunkt abgeschlossen ist
if not reachedConnection then
reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
-- Erhöhe den Wegpunkt-Index und bewege dich zum nächsten Wegpunkt
nextWaypointIndex += 1
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
end
end)
end
-- Bewegen Sie sich zunächst zum zweiten Wegpunkt (der erste Wegpunkt ist der starten; überspringen Sie ihn)
nextWaypointIndex = 2
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn("Path not computed!", errorMessage)
end
end
Blockierte Wege verwalten
Viele Roblox-Welten sind dynamisch; Teile können sich bewegen oder fallen und Böden können zusammenbrechen.Dies kann einen berechneten Pfad blockieren und verhindern, dass der Charakter sein Ziel erreicht.Um dies zu handhaben, kannst du das Path.Blocked-Ereignis verbinden und den Weg erneut berechnen, um alles, was es blockiert, zu umgehen.
LocalScript - Charakter-Pfadfindung
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)
-- Den Weg berechnen
local success, errorMessage = pcall(function()
path:ComputeAsync(character.PrimaryPart.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
-- Holen Sie sich die Wegpunkte
waypoints = path:GetWaypoints()
-- Erkennen, ob der Weg blockiert wird
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
-- Überprüfe, ob das Hindernis weiter auf dem Weg ist
if blockedWaypointIndex >= nextWaypointIndex then
-- Hör auf, den Wegblock zu erkennen, bis der Weg neu berechnet wird
blockedConnection:Disconnect()
-- Funktion aufrufen, um einen neuen Weg erneut zu berechnen
followPath(destination)
end
end)
end
end
Wegfindungsmodifizierer
Standardmäßig gibt Path:ComputeAsync() den kürzesten Weg zwischen dem Startpunkt und dem Ziel zurück, mit der Ausnahme, dass es versucht Sprünge zu vermeiden.Dies sieht in manchen Situationen unnatürlich aus - zum Instanzkann ein Weg durch Wasser gehen, anstatt über eine nahe Brücke, einfach weil der Weg durch Wasser geometrisch kürzer ist.

Um das Wegfinden weiter zu optimieren, können Sie Wegfindungsmodifizierer implementieren, um intelligente Wege über verschiedene Materialien , um definierte Regionen oder durch Hindernisse zu berechnen.
Setze Materialkosten
Wenn Sie mit Terrain und BasePart Materialien arbeiten, können Sie eine Costs Tabelle innerhalb von CreatePath() einfügen, um bestimmte Materialien zugänglicher zu machen als andere.Alle Materialien haben eine Standardkosten von 1 und jedes Material kann als nicht durchdringbar definiert werden, indem sein Wert auf math.huge gesetzt wird.
Die Schlüssel in der Costs Tabelle sollten Zeichennamen sein, die Enum.Material Namen darstellen, zum Beispiel Water für Enum.Material.Water.
LocalScript - Charakter-Pfadfindung
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}})
Arbeite mit Regionen
In einigen Fällen reicht die Materialpräferenz nicht aus.Zum Beispiel möchten Sie vielleicht, dass Charaktere eine definierte Region vermeiden, unabhängig von den Materialien unter den Füßen.Dies kann durch Hinzufügen eines PathfindingModifier Objekts zu einem Teil erreicht werden.
Erstelle ein Anchored Teil rund um die gefährliche Region und lege seine CanCollide Eigenschaft auf falsch fest.
Füge eine PathfindingModifier auf das Teil ein, suche ihre Eigenschaftenund weise einen sinnvollen Namen wie DangerZone zu.
Füge eine Costs Tabelle innerhalb von CreatePath() ein, die einen passenden Schlüssel und einen dazugehörigen numerischen Wert enthält.Ein Modifizierer kann als nicht durchdringbar definiert werden, indem sein Wert auf math.huge gesetzt wird.
LocalScript - Charakter-Pfadfindunglocal 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}})
Ignoriere Hindernisse
In einigen Fällen ist es nützlich, durch feste Hindernisse zu finden, als ob sie nicht existieren würden.Dies ermöglicht es Ihnen, einen Weg durch bestimmte physische Blocker zu berechnen, im Gegensatz zur Fehlberechnung.
Erstelle ein Anchored Teil um das Objekt herum und lege seine CanCollide Eigenschaft auf falsch fest.
Füge eine PathfindingModifier auf das Teil ein und aktiviere seine Eigenschaften.
Jetzt, wenn ein Weg vom Zombie-NPC zum Spielercharakter berechnet wird, verlängert sich der Weg über die Tür hinaus und du kannst den Zombie auffordern, ihn zu durchqueren.Selbst wenn der Zombie die Tür nicht öffnen kann, reagiert er, als ob er den Charakter hinter der Tür "hört".
Wegfindungs-Links
Manchmal ist es notwendig, einen Weg durch einen Raum zu finden, der nicht normal durchquert werden kann, wie über eine Kluft, und eine benutzerdefinierte Aktion auszuführen, um den nächsten Wegpunkt zu erreichen.Dies kann durch das PathfindingLink Objekt erreicht werden.
Mit dem Inselbeispiel oben kannst du den Agenten dazu bringen, ein Boot statt über alle Brücken zu gehen, zu verwenden.

Um eine PathfindingLink mit diesem Beispiel zu erstellen:
Um die Visualisierung und Fehlersuche zu unterstützen, schalte Wegfindungs-Links von der Visualisierungsoptionen Widget in der oberen rechten Ecke des 3D-Ansichtsfensters ein.
Erstelle zwei Attachments, eine auf dem Bootssitz und eine in der Nähe des Landeplatzes des Boots.
Erstellen Sie ein PathfindingLink in der Arbeitsumgebung und weisen Sie seine Anlage0 und Anlage1 Eigenschaften jeweils den Start- und End-Anhängen zu.
Weise einen sinnvollen Namen wie UseBoat auf seine Label Eigenschaftenzu.Dieser Name wird als Flagge im Wegfindungs-Skript verwendet, um eine benutzerdefinierte Aktion auszulösen, wenn der Agent den Start-Linkpunkt erreicht.
Füge eine Costs Tabelle innerhalb von CreatePath() ein, die sowohl einen Water Schlüssel als auch einen benutzerdefinierten Schlüssel enthält, der der Eigenschaftsname Label entspricht.Weise dem benutzerdefinierten Schlüssel einen niedrigeren Wert als Water zu.
LocalScript - Charakter-Pfadfindunglocal 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}})Im Ereignis, das abgefeuert wird, wenn ein Wegpunkt erreicht wird, füge einen benutzerdefinierten Check für den Label Modifizierungsnamen hinzu und führe eine andere Aktion aus als Humanoid:MoveTo() — in diesem Fall ruft eine Funktion auf, den Agenten im Boot zu platzieren, das Boot über das Wasser zu bewegen und den Weg des Agents bei der Ankunft auf der Zielinsel fortzusetzen.
LocalScript - Charakter-Pfadfindunglocal 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)-- Den Weg berechnenlocal success, errorMessage = pcall(function()path:ComputeAsync(character.PrimaryPart.Position, destination)end)if success and path.Status == Enum.PathStatus.Success then-- Holen Sie sich die Wegpunktewaypoints = path:GetWaypoints()-- Erkennen, ob der Weg blockiert wirdblockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)-- Überprüfe, ob das Hindernis weiter auf dem Weg istif blockedWaypointIndex >= nextWaypointIndex then-- Hör auf, den Wegblock zu erkennen, bis der Weg neu berechnet wirdblockedConnection:Disconnect()-- Funktion aufrufen, um einen neuen Weg erneut zu berechnenfollowPath(destination)endend)-- Erkennen, wenn die Bewegung zum nächsten Wegpunkt abgeschlossen istif not reachedConnection thenreachedConnection = humanoid.MoveToFinished:Connect(function(reached)if reached and nextWaypointIndex < #waypoints then-- Erhöhe den Wegpunkt-Index und bewege dich zum nächsten WegpunktnextWaypointIndex += 1-- Verwende Boot, wenn das Wegpunkt-Label "UseBoat" ist; ansonsten wechsle zum nächsten Wegpunktif waypoints[nextWaypointIndex].Label == "UseBoat" thenuseBoat()elsehumanoid:MoveTo(waypoints[nextWaypointIndex].Position)endelsereachedConnection:Disconnect()blockedConnection:Disconnect()endend)end-- Bewegen Sie sich zunächst zum zweiten Wegpunkt (der erste Wegpunkt ist der starten; überspringen Sie ihn)nextWaypointIndex = 2humanoid:MoveTo(waypoints[nextWaypointIndex].Position)elsewarn("Path not computed!", errorMessage)endendfunction useBoat()local boat = Workspace.BoatModelhumanoid.Seated:Connect(function()-- Starte das Bootsbewegung, wenn der Agent sitztif humanoid.Sit thentask.wait(1)boat.CylindricalConstraint.Velocity = 5end-- Kontritionsposition in Bezug auf die Insel erkennenlocal boatPositionConnectionboatPositionConnection = RunService.PostSimulation:Connect(function()-- Boot stoppen, wenn neben der Inselif boat.CylindricalConstraint.CurrentPosition >= 94 thenboatPositionConnection:Disconnect()boat.CylindricalConstraint.Velocity = 0task.wait(1)-- Agenten absetzen und weiter zum Zielhumanoid.Sit = falsehumanoid:MoveTo(waypoints[nextWaypointIndex].Position)endend)end)endfollowPath(TEST_DESTINATION)
Streaming-Kompatibilität
In-Experience Instanz-Streaming ist eine leistungsstarke Funktion, die 3D-Inhalte dynamisch laden und entladen kann, wenn sich der Charakter eines Spieler:inum die Welt bewegt.Wenn sie den Platzerkunden, gelangen neue Unter集合 des Raumstreams zu ihrem Gerät und einige der vorhandenen Unter集合 könnten ausgestreamt werden.
Betrachte die folgenden Best Practices für die Verwendung von PathfindingService in Streaming-fähigen Erlebnissen:
Streaming kann einen bestimmten Pfad blockieren oder entblocken, wenn ein Charakter entlang davon bewegt wird.Zum Beispiel, während ein Charakter durch einen Wald läuft, könnte ein Baum irgendwo vor ihnen fließen und den Weg behindern.Um das Pfadfinden mit Streaming nahtlos zu machen, wird dringend empfohlen, die Verwaltung von blockierten Pfaden-Technik zu verwenden und den Weg bei Bedarf erneut zu berechnen.
Ein häufiger Ansatz beim Wegfinden besteht darin, die Koordinaten bestehender Objekte für Berechnung zu verwenden, wie das Festlegen eines Wegziels auf die Position eines bestehenden Schatztruhenmodells in der Welt.Dieser Ansatz ist vollständig kompatibel mit serverseitiger Scripts seit der Server die volle Sicht auf die Welt zu jeder Zeit hat, aber LocalScripts und ModuleScripts die auf dem Client ausgeführt werden, können fehlschlagen, wenn sie versuchen, einen Weg zu einem Objekt zu berechnen, das nicht gestreamt wird.
Um dieses Problem zu lösen, erwägen Sie, die Zielposition auf die Position eines BasePart innerhalb eines dauerhaften Modells zu setzen.Beständige Modelle werden kurz nachdem der Spieler beigetreten ist, geladen und sie fließen nie aus, so dass ein Client-seitiges Skript sich mit dem PersistentLoaded-Ereignis verbinden und sicher auf das Modell zugreifen kann, um nach dem Feuern des Ereignisses Wegpunkte zu erstellen.