Wall Running, Rutschen und Kantenklettern machen moderne Actionspiele dynamisch. Versucht man, diese Mechaniken nur mit Standard-Humanoid-Zuständen zu bauen, kommt es häufig zu Rucklern und Stürzen.
Durch die Kombination moderner Luau-Physik-Constraints (`LinearVelocity`, `VectorForce`) mit gerichteten Raycasts lässt sich ein flüssiges AAA-Bewegungsgefühl auf allen Plattformen erzielen.
1. Humanoid-Zustände für flüssiges Parkour anpassen
Grundlagen benutzerdefinierter Zustandsautomaten:
- Konfliktzustände deaktivieren: Beim Start des Wall Runs Klettern und freien Fall deaktivieren, damit Standard-Animationen die Physik nicht blockieren.
- Network Ownership: Der Server übergibt das RootPart an den Client, um Eingabeverzögerungen bei der Bewegung auszuschließen.
- Modulare FSM: Trennung der Zustände in Gehen, Sprinten, WallRun, Hängen und Hochziehen mit klaren Übergängen.
2. Gerichtete Raycasts und Ausrichtung an der Wandnormale
Wanderkennung und Berechnung der Vorwärtsrichtung:
- Seitliche Raycast-Fühler: Horizontale Strahlen von Hüfte und Schultern (3,5 Studs) erkennen laufbare Wände.
- Normalen-Prüfung: Sicherstellen, dass die Wand senkrecht steht (75° bis 105° zur Vertikalen), um Schrägen auszuschließen.
- Kreuzprodukt für die Laufrichtung:
wallNormal:Cross(Vector3.yAxis)berechnet die Richtung parallel zur Wandoberfläche.
3. Moderne Physik-Constraints: LinearVelocity & VectorForce
Ersatz veralteter BodyMovers durch moderne Constraints:
- LinearVelocity für konstante Geschwindigkeit: Verhindert Geschwindigkeitsverlust durch seitliche Reibung an der Wand.
- VectorForce gegen die Schwerkraft: Kompensiert die Workspace-Gravitation (196,2 studs/s²) mit einer vertikalen Gegenkraft.
- Kraftabfall für Realismus: Die Aufwärtskraft nach 2 Sekunden langsam absenken, um ein natürliches Absinken einzuleiten.
-- Clientseitiger Wall Running Physik-Controller
local RunService = game:GetService("RunService")
local WallRun = {}
WallRun.__index = WallRun
function WallRun.new(character)
local self = setmetatable({}, WallRun)
self.Char = character
self.RootPart = character:WaitForChild("HumanoidRootPart")
self.Humanoid = character:WaitForChild("Humanoid")
local att = Instance.new("Attachment", self.RootPart)
local lv = Instance.new("LinearVelocity")
lv.Attachment0 = att
lv.MaxForce = 15000
lv.RelativeTo = Enum.ActuatorRelativeTo.World
lv.Enabled = false
lv.Parent = self.RootPart
self.Attachment = att
self.LinearVelocity = lv
self.IsRunning = false
return self
end
function WallRun:CheckWall(side)
local rightVec = self.RootPart.CFrame.RightVector
local rayDir = (side == "Left" and -rightVec or rightVec) * 3.5
local params = RaycastParams.new()
params.FilterDescendantsInstances = {self.Char}
params.FilterType = Enum.RaycastFilterType.Exclude
return workspace:Raycast(self.RootPart.Position, rayDir, params)
end
function WallRun:Start(hitNormal, forwardDir)
self.IsRunning = true
self.LinearVelocity.VectorVelocity = forwardDir * 32 + Vector3.new(0, 4, 0)
self.LinearVelocity.Enabled = true
self.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
end
function WallRun:Stop()
self.IsRunning = false
self.LinearVelocity.Enabled = false
self.Humanoid:ChangeState(Enum.HumanoidStateType.Freefall)
end
return WallRun
4. Kanten-Erkennung und Hochziehen (Mantle)
Kanten greifen und flüssig über Hindernisse klettern:
- Zweistufige Erkennung: Ein horizontaler Brust-Raycast prüft die Wand, ein vertikaler Strahl von oben ermittelt die Kantenhöhe.
- Positionseinrastung: Beim Greifen das RootPart mit
AlignPositionan der Kante fixieren. - Bézier-Kurve beim Klettern: Bei Sprungeingabe die Spielfigur in einem weichen Bogen über das Hindernis heben.
5. Touch-Steuerung und serverseitige Validierung
Mobile Bedienbarkeit und Schutz vor Geschwindigkeits-Cheats:
- Große Touch-Tasten: Sprung- und Kletteraktionen auf mindestens 48x48 Pixel große Schaltflächen legen.
- Geschwindigkeitsgrenzen auf dem Server: Der Server prüft Positionswechsel pro Tick und blockiert Teleport-Hacks.
- Wand-Gegenprüfung: Der Server führt eigene Raycasts durch, um zu prüfen, ob sich wirklich eine Wand neben dem Spieler befand.
Frequently Asked Questions
Warum sollte man LinearVelocity statt BodyVelocity verwenden?
BodyVelocity ist veraltet. LinearVelocity gehört zur modernen Physik-Engine von Roblox, arbeitet stabiler und berücksichtigt Massen präzise.
Wie verhindert man das Abrutschen von der Wand beim Wall Run?
Durch eine vertikale Kraft (VectorForce), die genau der Schwerkraft entgegenwirkt und nach kurzer Zeit graduell abklingt.
Wie berechnet man die Laufrichtung an der Wand?
Über das Kreuzprodukt aus Wandnormale und dem Aufwärtsvektor (0, 1, 0) der Spielwelt.
Wie werden Parkour-Cheats serverseitig verhindert?
Durch Überprüfung von Wand-Raycasts und strikte Geschwindigkeitskontrollen auf dem Server.