Dans beaucoup de jeux Roblox, il existe des zones spéciales qui changent complètement la manière de jouer. Imagine un sol où ton personnage se met à glisser tout seul, comme sur de la glace, sans pouvoir s’arrêter immédiatement. Ou encore une pente qui accélère ton déplacement, te propulsant vers une nouvelle plateforme. Ces effets simples transforment un niveau classique en un vrai parcours d’obstacles amusant et dynamique. Dans ce tutoriel, tu vas apprendre à créer ce type de mécanismes toi-même avec Lua dans Roblox Studio. Tu vas découvrir comment contrôler le comportement d’un joueur lorsqu’il touche une zone spéciale. Tu vas progresser étape par étape pour comprendre comment la physique du jeu peut être modifiée. À la fin, tu seras capable de concevoir tes propres zones de glisse comme dans les vrais jeux d’obby.
Ce tutoriel est organisé en trois parties :
- La première te montrera comment créer une plaque glissante simple pour faire “patiner” un joueur.
- La deuxième expliquera comment gérer une plaque en pente pour influencer la direction du déplacement.
- Enfin, la troisième partie te permettra de combiner plusieurs plaques glissantes pour créer un parcours complet et dynamique.
Plaque glissante
Crée un part puis dessous un script :

Ce script transforme une Part en surface glissante grâce à des propriétés physiques qui réduisent les frottements et lui donnent l’apparence de la glace. Lorsqu’un joueur touche cette Part, le script vérifie qu’il s’agit bien d’un personnage et récupère son HumanoidRootPart, qui représente le centre de son déplacement. Il calcule ensuite la direction dans laquelle regarde le joueur à l’aide du LookVector. La Part reçoit alors une vitesse SPEED qui la fait glisser dans la direction choisie pendant une durée définie SLIDER_LENGTH. Enfin, après ce délai, la vitesse est remise à zéro pour arrêter la glissade.
-- Script pour une part qui glisse sur un joueur lorsqu'il la touche
local part = script.Parent
-- Appliquer des propriétés physiques pour que la part soit glissante
part.CustomPhysicalProperties = PhysicalProperties.new(
0.7, -- Density
0, -- Friction
0, -- Elasticity
0, -- FrictionWeight
1 -- ElasticityWeight
)
-- Appliquer un matériau glissant comme de la glace
part.Material = Enum.Material.Ice
-- Vitesse de déplacement de la glissade
local SPEED = 15
local SLIDER_LENGTH = 1
-- Fonction appelée lorsque la part est touchée
part.Touched:Connect(function(hit)
-- Vérifier si l'objet touché est un personnage
local character = hit:FindFirstAncestorOfClass("Model")
if not character then return end
-- Récupérer le joueur et sa racine
local rootPart = character:FindFirstChild("HumanoidRootPart")
if not rootPart then return end
-- Récupérer la direction de la caméra du joueur
local dir = rootPart.CFrame.LookVector
-- Appliquer une impulsion sur la part pour faire glisser le joueur dans la direction de la caméra
part.AssemblyLinearVelocity = dir * SPEED
-- Arrêter la glissade après un délai
task.spawn(function()
task.wait(SLIDER_LENGTH)
part.AssemblyLinearVelocity = Vector3.zero
end)
end)
Pente glissante

Modifie le code pour permettre à la plaque glissante de tenir compte de son inclinaison.
Une nouvelle fonction, getSurfaceInclination, calcule la direction naturelle de la pente à partir de la gravité et de la normale de la surface. La gravité indique toujours le bas, tandis que la normale renseigne sur l’orientation de la plaque. En combinant ces deux informations, le script détermine la direction dans laquelle un objet glisserait naturellement sur la pente.
Lorsque le joueur touche la plaque, le script calcule cette direction de glissade et vérifie si elle est suffisamment importante. Si la plaque est inclinée, la vitesse est appliquée dans le sens de la pente afin de simuler une descente naturelle. Si la plaque est horizontale, il n’y a pas de direction de pente significative : le joueur glisse alors dans la direction vers laquelle il regarde. Grâce à cet ajout, le même script peut gérer aussi bien une plaque plate qu’une plaque inclinée, ce qui rend le comportement plus réaliste et permet de créer des parcours plus variés.
-- Script pour une part qui glisse sur un joueur lorsqu'il la touche
local part = script.Parent
-- Appliquer des propriétés physiques pour que la part soit glissante
part.CustomPhysicalProperties = PhysicalProperties.new(
0.7, -- Density
0, -- Friction
0, -- Elasticity
0, -- FrictionWeight
1 -- ElasticityWeight
)
-- Appliquer un matériau glissant comme de la glace
part.Material = Enum.Material.Ice
-- Vitesse de déplacement de la glissade
local SPEED = 15
local SLIDER_LENGTH = 1
local function getSurfaceInclination(hit)
-- Récupérer la direction de la gravité
local gravity = Vector3.new(0, -1, 0)
-- Récupérer la normale de la surface de la part
-- la normale est un vecteur unitaire perpendiculaire à la surface
-- qui indique “dans quel sens la surface est orientée"
local normal = part.CFrame.UpVector
-- enlève la composante perpendiculaire à la surface
local slopeDirection = gravity - normal * gravity:Dot(normal)
return slopeDirection.Unit
end
-- Fonction appelée lorsque la part est touchée
part.Touched:Connect(function(hit)
-- Vérifier si l'objet touché est un personnage
local character = hit:FindFirstAncestorOfClass("Model")
if not character then return end
-- Récupérer le joueur et sa racine
local rootPart = character:FindFirstChild("HumanoidRootPart")
if not rootPart then return end
-- Récupérer la direction de la caméra du joueur
local dir = rootPart.CFrame.LookVector
-- Récuoération du sens de la pente de la part par rapport à la gravité
local slopeDirection = getSurfaceInclination(part)
-- Glissade en fonction si pente de la part ou part horizontale
if slopeDirection.Magnitude > 0.1 then
-- Appliquer une impulsion sur la part pour faire glisser le joueur dans la direction de la pente
part.AssemblyLinearVelocity = slopeDirection * SPEED
else
-- Appliquer une impulsion sur la part pour faire glisser le joueur dans la direction de la caméra
part.AssemblyLinearVelocity = dir * SPEED
-- Arrêter la glissade après un délai
task.spawn(function()
task.wait(SLIDER_LENGTH)
part.AssemblyLinearVelocity = Vector3.zero
end)
end
end)
Systèmes de plaques et pentes glissantes

Dans cette nouvelle version, le script ne gère plus une seule plaque glissante mais un ensemble de plaques regroupées dans un dossier (Folder). Au démarrage, le script récupère tous les objets contenus dans ce dossier puis les parcourt un par un grâce à une boucle.
local folder = script.Parent
local parts = folder:GetChildren()
for _, part in pairs(parts) do
end
Une vérification est effectuée pour s’assurer que chaque objet est bien une BasePart afin d’éviter les erreurs avec d’autres types d’objets.
if not part:IsA("BasePart") then continue end
Pour chaque plaque trouvée, les propriétés physiques et le matériau de glace sont appliqués automatiquement. Cela évite de dupliquer le même script sur chaque plaque du parcours. La fonction de calcul de la pente est ensuite associée à chaque plaque afin que son inclinaison soit prise en compte individuellement. Enfin, un événement Touched est créé pour chacune d’elles : lorsqu’un joueur touche une plaque, le script utilise les caractéristiques propres à cette plaque (orientation, pente, vitesse de glisse) pour déterminer son déplacement.
Grâce à cette modification, il devient très simple de créer un parcours complet composé de nombreuses surfaces glissantes. Il suffit d’ajouter ou de supprimer des plaques dans le dossier pour que le script les prenne automatiquement en charge, sans aucune modification supplémentaire du code.
-- Script pour une part qui glisse sur un joueur lorsqu'il la touche
local folder = script.Parent
local parts = folder:GetChildren()
for _, part in pairs(parts) do
if not part:IsA("BasePart") then continue end
-- Appliquer des propriétés physiques pour que la part soit glissante
part.CustomPhysicalProperties = PhysicalProperties.new(
0.7, -- Density
0, -- Friction
0, -- Elasticity
0, -- FrictionWeight
1 -- ElasticityWeight
)
-- Appliquer un matériau glissant comme de la glace
part.Material = Enum.Material.Ice
-- Vitesse de déplacement de la glissade
local SPEED = 15
local SLIDER_LENGTH = 3
local function getSurfaceInclination(hit)
-- Récupérer la direction de la gravité
local gravity = Vector3.new(0, -1, 0)
-- Récupérer la normale de la surface de la part
-- la normale est un vecteur unitaire perpendiculaire à la surface
-- qui indique “dans quel sens la surface est orientée"
local normal = part.CFrame.UpVector
-- enlève la composante perpendiculaire à la surface
local slopeDirection = gravity - normal * gravity:Dot(normal)
return slopeDirection.Unit
end
-- Fonction appelée lorsque la part est touchée
part.Touched:Connect(function(hit)
-- Vérifier si l'objet touché est un personnage
local character = hit:FindFirstAncestorOfClass("Model")
if not character then return end
-- Récupérer le joueur et sa racine
local rootPart = character:FindFirstChild("HumanoidRootPart")
if not rootPart then return end
-- Récupérer la direction de la caméra du joueur
local dir = rootPart.CFrame.LookVector
-- Récuoération du sens de la pente de la part par rapport à la gravité
local slopeDirection = getSurfaceInclination(part)
-- Glissade en fonction si pente de la part ou part horizontale
if slopeDirection.Magnitude > 0.1 then
-- Appliquer une impulsion sur la part pour faire glisser le joueur dans la direction de la pente
part.AssemblyLinearVelocity = slopeDirection * SPEED
else
-- Appliquer une impulsion sur la part pour faire glisser le joueur dans la direction de la caméra
part.AssemblyLinearVelocity = dir * SPEED
-- Arrêter la glissade après un délai
task.spawn(function()
task.wait(SLIDER_LENGTH)
part.AssemblyLinearVelocity = Vector3.zero
end)
end
end)
end
