Der Standard-Humanoid in Roblox reicht für einfache Welten aus, stößt jedoch bei schnellen Plattformern und Action-Titeln an seine Grenzen.
Mit einem maßgeschneiderten, physikgetriebenen Controller behalten Entwickler die volle Kontrolle. Schwebende Kapseln via VectorForce und Raycast-Bodenberechnungen garantieren flüssige Bewegungsabläufe auf jedem Terrain.
1. Schwächen des nativen Humanoid-Systems
Warum kompetitive Spiele eigene Physik-Controller erfordern:
- Starre Zustandsmaschine: Verzögerte Zustandswechsel behindern blitzschnelle Richtungswechsel.
- Netzwerk-Physik-Bugs: Kollisionen auf beweglichen Plattformen führen oft zu unkontrolliertem Schleudern.
- Ruckartige Stufen: Sprunghafte Höhenanpassungen stören den visuellen Fluss der Kamera.
- Deterministische Kontrolle: Mathematisch exakte Geschwindigkeitsberechnung im Heartbeat-Takt.
2. Die schwebende Kapsel mit VectorForce-Federung
Berührungslose Fortbewegung für geschmeidiges Überqueren von Hindernissen:
- Virtuelle Federung: Ein nach unten gerichteter Raycast federt das Gewicht des Charakters dynamisch ab.
- Reibungslose Hülle: Eine glatte Kapsel mit Reibungswert Null verhindert das Hängenbleiben an Kanten.
- AlignOrientation-Aufrichtung: Hält den Charakter stabil aufrecht bei freier Drehung.
- LinearVelocity: Direkte Geschwindigkeitssteuerung ohne träge Beschleunigungsphasen.
--!strict
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local CustomController = {}
local player = Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hrp = char:WaitForChild("HumanoidRootPart") :: BasePart
local TARGET_HEIGHT = 4.2
local SPRING_STIFFNESS = 1800
local SPRING_DAMPING = 160
local WALK_SPEED = 24
local RAY_PARAMS = RaycastParams.new()
RAY_PARAMS.FilterType = RaycastFilterType.Exclude
local linearVelocity = Instance.new("LinearVelocity")
linearVelocity.MaxForce = 40000
linearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
linearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World
local attachment = Instance.new("Attachment")
attachment.Parent = hrp
linearVelocity.Attachment0 = attachment
linearVelocity.Parent = hrp
function CustomController.Update(dt: number)
local moveDir = Vector3.zero
local cam = Workspace.CurrentCamera
if UserInputService:IsKeyDown(Enum.KeyCode.W) then moveDir += cam.CFrame.LookVector end
if UserInputService:IsKeyDown(Enum.KeyCode.S) then moveDir -= cam.CFrame.LookVector end
if UserInputService:IsKeyDown(Enum.KeyCode.D) then moveDir += cam.CFrame.RightVector end
if UserInputService:IsKeyDown(Enum.KeyCode.A) then moveDir -= cam.CFrame.RightVector end
moveDir = Vector3.new(moveDir.X, 0, moveDir.Z)
if moveDir.Magnitude > 0.01 then moveDir = moveDir.Unit end
RAY_PARAMS.FilterDescendantsInstances = { char }
local ray = Workspace:Raycast(hrp.Position, Vector3.new(0, -TARGET_HEIGHT * 1.5, 0), RAY_PARAMS)
local vForce = 0
local targetVel = moveDir * WALK_SPEED
if ray and ray.Instance and ray.Instance.CanCollide then
local dist = (hrp.Position - ray.Position).Magnitude
targetVel = moveDir - (ray.Normal * moveDir:Dot(ray.Normal))
targetVel = targetVel.Unit * WALK_SPEED
local err = TARGET_HEIGHT - dist
vForce = (err * SPRING_STIFFNESS) - (hrp.AssemblyLinearVelocity.Y * SPRING_DAMPING)
end
linearVelocity.VectorVelocity = Vector3.new(targetVel.X, targetVel.Y + (vForce * dt), targetVel.Z)
end
RunService.Heartbeat:Connect(CustomController.Update)
return CustomController
3. Raycast-Bodenprüfung und Hang-Projektion
Mathematische Anpassung von Bewegungsvektoren an schräges Terrain:
- Normalenvektor-Erkennung: Ermittlung der Bodensteigung aus Raycast-Treffern.
- Projektion: Anpassung der horizontalen Eingabe an die Neigung der Fläche.
- Hang-Grenzwinkel: Automatisches Rutschen bei Neigungen über 45 Grad.
- Kantenüberhang: Erkennung von Abgründen vor dem Betreten des Vakuums.
4. Trägheit, Schwung und dynamisches Rutschen
Umsetzung anspruchsvoller Parkour- und Bewegungselemente:
- Gleit-Mechanik: Temporäres Aufheben von Bremskräften beim Ducken aus vollem Lauf.
- Abwärtsbeschleunigung: Physikalischer Geschwindigkeitsbonus beim Rutschen auf Gefällen.
- Schwungerhaltung: Weiche Übergänge nach Sprüngen und Rutschphasen.
- Air-Control: Präzise Luftsteuerung ohne unendliche Geschwindigkeitszunahme.
5. Prozedurale Bewegung und Animationssynchronisation
Perfekte Abstimmung von 3D-Skelett und physikalischer Geschwindigkeit:
- Fußrutsch-Beseitigung: Skalierung der Animationsabspielrate an die gemessene Fortbewegungsgeschwindigkeit.
- Mischbäume: Dynamische 8-Wege-Vektorüberblendung.
- IK-Fußanpassung: Exakte Ausrichtung der Fußsohlen an unebenem Terrain via IKControl.
- Client-Rechenhoheit: Lokale Physikberechnungen schonen Serverressourcen.
Frequently Asked Questions
Warum sollte die Kapsel den Boden nicht physisch berühren?
Direkter Bodenkontakt führt zu Verhakungen an Voxel-Kanten; eine schwebende Kapsel gleitet störungsfrei.
Wie verhindert die Projektion Geschwindigkeitsverlust an Steigungen?
Sie leitet die Energie parallel zur Steigung um, statt gegen die Kollisionsfläche zu drücken.
Werden Plattform-Schleuderfehler behoben?
Ja, da die Geschwindigkeit der Plattform direkt in den Bewegungsvektor des Charakters eingerechnet werden kann.