L'eau de terrain par défaut de Roblox est adaptée à la nage, mais ne permet pas de simuler des embarcations réalistes à haute vitesse sans oscillation ni désynchronisation.
En concevant un contrôleur de flottabilité multipoint basé sur le principe d'Archimède et les vagues de Gerstner en Luau, les développeurs obtiennent des navires naviguant naturellement sur les vagues avec un contrôle total.
1. Limites de l'Eau de Terrain Native pour les Embarcations
Pourquoi l'eau native de Roblox échoue sur les véhicules marins complexes :
- Poussée homogène : Accélération verticale uniforme sans gestion du tangage ni du roulis.
- Surface statique : Absence de houle 3D et de vagues de tempête dynamiques.
- Expulsions physiques à haute vitesse : Instabilité lors des collisions rapides avec l'eau.
- Absence d'amortissement de gîte : Tendance continue au chavirement sans couple de rappel.
2. Flottabilité Multipoint d'Archimède & Vagues de Gerstner
Calcul des forces de poussée sur des points distribués de la coque :
- Échantillonnage aux quatre coins de la coque : Attachments indépendants mesurant l'immersion.
- Formule de Gerstner en Luau : Calcul instantané de la hauteur d'eau sans maillage complexe.
- Force d'Archimède amortie : `F = (Immersion * Volume * Gravité * Densité) - (Vitesse * Amortissement)`.
- Couple de redressement naturel : Équilibre hydrostatique stable face aux fortes vagues.
--!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. Traînée Anisotrope & Hydrodynamique de Coque
Modélisation des frottements et de la résistance de l'eau sur le bateau :
- Traînée anisotrope : Faible résistance vers l'avant (~0.05) et forte résistance latérale (~1.2).
- Passage en déjaugeage : Transition entre mode déplacement et hydroplanage à pleine vitesse.
- Amortissement angulaire : Suppression des oscillations résiduelles en tangage et roulis.
- Propulsion par hélice arrière : Virage naturel avec inclinaison vers l'intérieur de la courbe.
4. Propriété Réseau & Synchronisation Sans Saccade
Architecture réseau pour des bateaux multijoueurs fluides :
- Attribution de Network Ownership au pilote pour zéro temps de latence au volant.
- Vagues déterministes calculées simultanément sur le serveur et les clients.
- Stabilisation des passagers pour éviter les expulsions lors des sauts de vagues.
- Mise en veille des navires vides pour économiser les ressources serveur.
5. Bonnes Pratiques de Production
Checklist pour un système maritime sans bugs dans Roblox Studio :
- Centre de gravité abaissé sous la ligne de flottaison.
- Coques de collision simplifiées sans friction pour éviter les blocages.
- Particules d'écume et effets sonores modulés en fonction de la vitesse.
- Déformation de surface visuelle synchronisée aux équations de vagues.
Frequently Asked Questions
Pourquoi privilégier les vagues de Gerstner au terrain Roblox ?
Le terrain est fixe ; les vagues de Gerstner permettent des houles animées réalistes sans échange réseau de géométrie.
Combien de points de flottabilité utiliser ?
4 points aux extrémités de la coque suffisent pour les vedettes rapides ; 6 à 8 points pour les gros navires.
Comment empêcher le bateau de s'envoler lors des sauts ?
En plafonnant la force de poussée maximale et en appliquant une traînée aérodynamique.