Das Standard-Terrainwasser in Roblox bietet einfache Schwimmmechaniken für Avatare, reicht jedoch für anspruchsvolle maritime Simulationen, Schnellboote und Seeschlachten nicht aus.
Mit einem Mehrpunkt-Auftriebssystem berechnen Entwickler archimedische Auftriebskräfte an jedem Rumpfpunkt separat. In Kombination mit Luau-Gerstner-Wellen und Strömungswiderstands-Tensoren bewegen sich Schiffe physikalisch stabil auf dynamischen Wellen.
1. Warum Standard-Terrainwasser für Schiffe unzureichend ist
Technische Grenzen des nativen Roblox-Wassers bei komplexen Wasserfahrzeugen:
- Homogener Bounding-Box-Auftrieb: Standardwasser wendet gleichförmige Beschleunigung an, was Neigungswinkel und Rumpfkrängung verhindert.
- Flache Wasseroberfläche: Nativ verformt sich Terrainwasser nicht zu dreidimensionalen Wellenkämmen.
- Instabilität bei hohen Geschwindigkeiten: Schnelle Boote erleiden extreme Stoßimpulse bei Kollisionen mit Wasseroberflächen.
- Mangelnde Roll-Dämpfung: Ohne gezielte Strömungswiderstandskraft kentern Boote bei scharfen Wendemanövern.
2. Mehrpunkt-Archimedes-Auftrieb & Gerstner-Wellensampling
Berechnung von Auftriebskräften an verteilten Rumpfpunkten:
- Vierpunkt-Rumpfsampling: Attachments an Bug und Heck (links/rechts) tasten die Wassertiefe unabhängig ab.
- Analytische Gerstner-Wellenformel: Mathematische Höhenberechnung an beliebigen Koordinaten `(X, Z)` ohne Geometrie-Meshes.
- Verdrängungsvolumen & Auftriebskraft: Berechnung über `F = (Tiefe * Volumen * Gravitation * Dichte) - (Geschwindigkeit * Dämpfung)`.
- Aufrichtendes Drehmoment: Asymmetrischer Auftrieb richtet den Schiffsrumpf in rauer See automatisch auf.
--!strict
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local BoatPhysics = {}
local WAVES = {
{Dir = Vector2.new(1, 0).Unit, Steepness = 0.4, Length = 60, Speed = 12},
{Dir = Vector2.new(0.7, 0.7).Unit, Steepness = 0.25, Length = 35, Speed = 9}
}
local GRAVITY = Workspace.Gravity
local WATER_DENSITY = 1.025
local POINT_SUBMERGED_VOLUME = 850
local DAMPING = 280
function BoatPhysics.GetWaveHeight(worldX: number, worldZ: number, timeVal: number): number
local elevation = 0
for _, wave in ipairs(WAVES) do
local k = (2 * math.pi) / wave.Length
local c = wave.Speed
local dot = wave.Dir.X * worldX + wave.Dir.Y * worldZ
local phase = k * (dot - c * timeVal)
elevation += math.sin(phase) * (wave.Steepness / k)
end
return elevation
end
function BoatPhysics.UpdateBuoyancy(hullRoot: BasePart, sampleAttachments: {Attachment}, vectorForces: {VectorForce})
local t = Workspace:GetServerTimeNow()
for i, attach in ipairs(sampleAttachments) do
local pos = attach.WorldPosition
local waterY = BoatPhysics.GetWaveHeight(pos.X, pos.Z, t)
local depth = waterY - pos.Y
local vf = vectorForces[i]
if depth > 0 then
local vel = hullRoot:GetVelocityAtPosition(pos)
local upwardForce = math.clamp((depth * POINT_SUBMERGED_VOLUME * GRAVITY * WATER_DENSITY) - (vel.Y * DAMPING), 0, 80000)
local lateralDrag = -Vector3.new(vel.X, 0, vel.Z) * 45
vf.Force = Vector3.new(lateralDrag.X, upwardForce, lateralDrag.Z)
else
vf.Force = Vector3.zero
end
end
end
return BoatPhysics
3. Strömungswiderstands-Tensoren & Hydrodynamik
Mathematische Modellierung von Wasserwiderstand am Rumpf:
- Anisotroper quadratischer Widerstand: Geringer Widerstand entlang des Kiels (~0.05), hoher Querwiderstand (~1.2).
- Gleit- vs. Verdrängerfahrt: Übergang vom Verdrängen des Wassers zum dynamischen Gleiten bei hoher Geschwindigkeit.
- Winkelgeschwindigkeits-Dämpfung: Begrenzung von Schaukelbewegungen über Drehmomentbegrenzer.
- Heckantrieb & Rudervektoren: Realistische Krängung nach innen bei Kurvenfahrten.
4. Netzwerk-Eigentümerschaft & Replikation
Nahtlose Synchronisation zwischen Steuermann und Beobachtern:
- Driver Network Ownership: Zuweisung von `SetNetworkOwner(player)` für latenzfreie Steuerung.
- Deterministische Wellen: Alle Clients berechnen identische Wellenhöhen synchron über Serverzeit.
- Passagier-Stabilisierung: Befestigung über Seat-Attachments gegen unbeabsichtigtes Herausschleudern.
- Schlafmodus für leere Boote: Ressourcenersparnis durch Pausieren der Physik bei unbemannten Schiffen.
5. Best Practices & Produktions-Checkliste
Entwicklungsrichtlinien für performante Roblox-Schiffe:
- Schwerpunktlage unter Wasserlinie: Verhindert unkontrolliertes Kentern.
- Kollisionsvereinfachung: Unsichtbare reibungsfreie Hüllenblöcke verhindern Hängenbleiben.
- Partikel- & Soundeffekte: Geschwindigkeitsabhängige Schaumkronen und Motorsounds.
- Mesh-Deformation: Visuelle Übereinstimmung der Wasserwellen mittels Bone-Rigging.
Frequently Asked Questions
Warum Gerstner-Wellen statt Terrain-Raycasts?
Terrainwasser ist statisch; Gerstner-Wellen ermöglichen synchrone, hochdynamische Ozeanwellen ohne Server-Mesh-Übertragung.
Wie viele Auftriebspunkte sind optimal?
4 Punkte an den Rumpfecken genügen für normale Boote; Großschiffe nutzen 6 bis 8 Punkte.
Wie verhindert man Katapultflüge bei Wellenkontakt?
Begrenzen der maximalen Auftriebskraft pro Frame und Einbeziehung aerodynamischer Dämpfung.