Voir le tutoriel : Déplacer une Part avec la Physique Roblox
Apprendre une version avancée de la fonction mouvement qui :
- Calcule le déplacement restant frame par frame (comme Pythagore en 3D).
- S’arrête exactement sur la cible (sans la dépasser).
- Donne à la
Partune vélocité physique réelle pendant le mouvement. - Utilise
CustomPhysicalPropertiespour contrôler la physique de laPart.
Introduction : Qu’est-ce qui change par rapport au tutoriel précédent ?
Dans le tutoriel précédent, la fonction mouvement fonctionnait ainsi :
- On calculait un déplacement fixe :
direction * speed * deltaTime. - On s’arrêtait quand la distance parcourue dépassait ou atteignait la cible.
- Problème : à la dernière frame, la
Partpouvait dépasser légèrement la cible (elle ne s’arrêtait pas pile au bon endroit).
Dans ce nouveau script, on corrige ce problème et on ajoute des améliorations :
| Aspect | Tutoriel précédent | Ce tutoriel |
|---|---|---|
| Cible | On mesure la distance depuis le départ. | On mesure la distance restante jusqu’à la cible. |
| Dernière frame | La Part peut dépasser la cible. | math.min permet de s’arrêter exactement sur la cible. |
| Position | Modifiée avec part.Position. | Modifiée avec part.CFrame = CFrame.new(newPosition). |
| Physique | Aucune vélocité. | On donne une vélocité réelle (AssemblyLinearVelocity) à la Part. |
| Direction | Normalisée dès le départ avec direction.Unit. | Calculée à chaque frame avec toTarget.Unit. |
| Arrêt | Vitesse « coupée » brutalement. | Vélocité remise à zéro proprement à l’arrêt. |
Préparation dans Roblox Studio

- Dans
Workspace, crée un dossierFolder. - Ajoute une
PartnomméePartdans ce dossier. - Crée un
ScriptdansServerScriptServiceet copie-y le code. - Lance le jeu :
- Après 5 secondes, la
Partmonte (axe Y) à 30 studs/seconde. - Elle s’arrête exactement après 100 unités, sans dépasser.
- Après 5 secondes, la
Script Commenté :
-- Récupérer le service RunService pour utiliser Heartbeat
local RunService = game:GetService("RunService")
-- Récupérer le dossier "Folder" et la Part à déplacer
local folder = workspace:WaitForChild("Folder")
local part = folder:WaitForChild("Part")
-- Configurer les propriétés physiques personnalisées de la Part
part.CustomPhysicalProperties = PhysicalProperties.new(
1, -- Density (densité) : masse par unité de volume
0.3, -- Friction (frottement) : glisse un peu sur les surfaces
0, -- Elasticity (rebond) : ne rebondit pas du tout
1, -- FrictionWeight : importance du frottement
1 -- ElasticityWeight : importance du rebond
)
-- Fonction pour déplacer une Part jusqu'à une cible, à vitesse contrôlée
-- Paramètres :
-- part : la Part à déplacer
-- targetDistance : distance totale à parcourir
-- direction : direction du mouvement (Vector3)
-- speed : vitesse en studs par seconde
local function mouvement(part, targetDistance, direction, speed)
-- Ancrer la Part pour la contrôler manuellement (pas de gravité pendant le mouvement)
part.Anchored = true
-- Stocker la position de départ
local startPosition = part.Position
-- Calculer la position de la cible (point d'arrivée)
local target = startPosition + (direction * targetDistance)
-- Variable pour stocker la connexion à Heartbeat
local connection
connection = RunService.Heartbeat:Connect(function(deltaTime)
-- Position actuelle de la Part
local currentPosition = part.Position
-- Vecteur restant jusqu'à la cible
local toTarget = target - currentPosition
-- Distance restante : longueur du vecteur toTarget
-- C'est le théorème de Pythagore en 3D :
-- distance = racine(x^2 + y^2 + z^2)
local remainingDistance = toTarget.Magnitude
-- Distance qu'on peut réellement parcourir cette frame :
-- on prend la PLUS PETITE valeur entre (speed * deltaTime) et (remainingDistance)
-- --> évite de dépasser la cible à la dernière frame !
local step = math.min(speed * deltaTime, remainingDistance)
-- Direction unitaire (longueur 1) vers la cible
local moveDirection = toTarget.Unit
-- Nouvelle position : position actuelle + direction * step
local newPosition = currentPosition + moveDirection * step
-- Appliquer la nouvelle position via CFrame
part.CFrame = CFrame.new(newPosition)
-- Donner à la Part une vélocité réelle correspondant au déplacement effectué
-- velocity = déplacement / temps
-- Cela rend le mouvement "visible" pour la physique de Roblox
part.AssemblyLinearVelocity = (newPosition - currentPosition) / deltaTime
-- Si la distance restante est plus petite que le pas, on est arrivé !
if remainingDistance <= step then
-- Remettre la vélocité à zéro (arrêt propre)
part.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
-- Déconnecter Heartbeat pour arrêter le mouvement
connection:Disconnect()
end
end)
end
-- Attendre 5 secondes avant de commencer
task.wait(5)
-- Paramètres du mouvement
local speed1 = 30 -- 30 studs par seconde
local direction1 = Vector3.new(0, 1, 0) -- Direction : vers le haut (axe Y)
local targetDistance1 = 100 -- 100 unités à parcourir
-- Lancer le mouvement
mouvement(part, targetDistance1, direction1, speed1)
Explications Détaillées
1. Les propriétés physiques personnalisées
part.CustomPhysicalProperties = PhysicalProperties.new(1, 0.3, 0, 1, 1)
PhysicalProperties.newpermet de contrôler exactement le comportement physique de laPart:
| Paramètre | Valeur | Signification |
|---|---|---|
| Density (densité) | 1 | Poids de la Part par unité de volume. |
| Friction (frottement) | 0.3 | Elle glisse un peu sur les surfaces (0 = glisse parfaitement, 1 = accroche). |
| Elasticity (rebond) | 0 | Elle ne rebondit pas du tout (0 = pas de rebond). |
| FrictionWeight | 1 | Importance de notre frottement face aux autres surfaces. |
| ElasticityWeight | 1 | Importance de notre rebond face aux autres surfaces. |
- Pourquoi c’est utile ici ?
- Comme on donne une vélocité à la
Part, on veut contrôler comment elle réagirait en cas de collision (pas de rebond, frottement connu).
- Comme on donne une vélocité à la
2. Calculer la distance restante (Pythagore en 3D)
local toTarget = target - currentPosition
local remainingDistance = toTarget.Magnitude
target - currentPosition:- Vecteur qui pointe de la position actuelle vers la cible.
.Magnitude:- Longueur de ce vecteur = distance restante.
- C’est le théorème de Pythagore en 3D :
distance = √(x² + y² + z²)
- Différence avec le tutoriel précédent :
- Avant : on mesurait la distance depuis le départ (distance parcourue).
- Maintenant : on mesure la distance restant jusqu’à la cible.
- C’est plus précis : même si la
Partétait déplacée par autre chose, le calcul resterait juste !
3. math.min : le secret de l’arrêt exact
local step = math.min(speed * deltaTime, remainingDistance)
math.min(a, b)retourne la plus petite des deux valeurs.- Deux cas possibles :
| Cas | Comparaison | Résultat |
|---|---|---|
| Milieu du mouvement | speed * deltaTime < remainingDistance | On avance normalement de speed * deltaTime. |
| Dernière frame | speed * deltaTime > remainingDistance | On avance exactement de remainingDistance → on tombe pile sur la cible ! |
- Exemple concret :
- Il reste 0.4 studs à parcourir, mais
speed * deltaTime = 0.5. - Ancienne méthode : on avancerait de 0.5 → la
Partdépasse la cible de 0.1 ! - Nouvelle méthode :
math.min(0.5, 0.4) = 0.4→ laParts’arrête exactement sur la cible.
- Il reste 0.4 studs à parcourir, mais
4. Déplacer avec CFrame
part.CFrame = CFrame.new(newPosition)
CFrame.new(position)crée unCFrame(position + rotation) à la position donnée.- Différence avec
part.Position = newPosition:Positionne déplace que la position géométrique de laPart.CFramedéplace toute la Part de manière complète (utile pour les Model et les assemblies).
- Les deux fonctionnent ici, mais
CFrameest la méthode recommandée pour déplacer des objets dans Roblox.
5. La vélocité réelle
part.AssemblyLinearVelocity = (newPosition - currentPosition) / deltaTime
- Pourquoi faire ça alors que la
Partest ancrée ?- La formule de la vitesse : vitesse = distance / temps.
- Ici : déplacement de la frame ÷ durée de la frame = vélocité exacte en studs/seconde.
- Cela informe le moteur physique de Roblox sur le mouvement réel de la
Part. - Avantage : si un joueur touche la
Partpendant son déplacement, les collisions et les effets seront cohérents avec le mouvement réel.
6. L’arrêt propre
if remainingDistance <= step then
part.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
connection:Disconnect()
end
- Condition : si la distance restante est plus petite que (ou égale à) le pas, c’est qu’on est arrivé.
- On remet la vélocité à zéro (
Vector3.new(0, 0, 0)) pour un arrêt propre, puis on déconnecteHeartbeat.
QCM : Teste ta compréhension !
Sur les différences avec le tutoriel précédent :
- Quelle est la principale amélioration de ce script par rapport au précédent ?
- a) La
Parts’arrête exactement sur la cible grâce àmath.min. - b) La
Partva plus vite. - c) La
Partchange de couleur.
- a) La
- Dans le tutoriel précédent, quel problème pouvait survenir à la dernière frame ?
- a) La
Partpouvait dépasser légèrement la cible. - b) La
Partne bougeait pas. - c) La
Partdisparaissait.
- a) La
- Comment mesure-t-on la distance dans ce script ?
- a) La distance restante jusqu’à la cible (
toTarget.Magnitude). - b) La distance parcourue depuis le départ.
- c) On ne mesure pas la distance.
- a) La distance restante jusqu’à la cible (
Sur math.min :
- Que fait
math.min(0.5, 0.4)?- a) Retourne
0.4(la plus petite valeur). - b) Retourne
0.5(la plus grande valeur). - c) Retourne
0.9(la somme).
- a) Retourne
- Pourquoi
math.minest-il essentiel ici ?- a) Pour éviter que la
Partdépasse la cible à la dernière frame. - b) Pour accélérer la
Part. - c) Pour changer la couleur de la
Part.
- a) Pour éviter que la
Sur la physique :
- Que fait
part.CustomPhysicalProperties = PhysicalProperties.new(1, 0.3, 0, 1, 1)?- a) Définit la densité, le frottement et le rebond de la
Part. - b) Définit la couleur de la
Part. - c) Déplace la
Part.
- a) Définit la densité, le frottement et le rebond de la
- Que signifie
Elasticity = 0dans les propriétés physiques ?- a) La
Partne rebondit pas du tout. - b) La
Partrebondit parfaitement. - c) La
Partest invisible.
- a) La
- Pourquoi calcule-t-on
AssemblyLinearVelocity = (newPosition - currentPosition) / deltaTime?- a) Pour donner à la Part une vitesse physique réelle (distance / temps).
- b) Pour téléporter la
Part. - c) Pour changer la couleur de la
Part.
- Pourquoi remet-on
AssemblyLinearVelocityàVector3.new(0, 0, 0)à l’arrêt ?- a) Pour un arrêt propre de la
Part. - b) Pour redémarrer le mouvement.
- c) Pour supprimer la
Part.
- a) Pour un arrêt propre de la
- Quel est l’avantage de mesurer la distance restante plutôt que la distance parcourue ?
- a) Le calcul reste correct même si la
Partest déplacée par autre chose en cours de route. - b) Le script est plus court.
- c) La
Partva plus vite
- a) Le calcul reste correct même si la
