Catégories
Jeu vidéo ROBLOX

Comment pousser un bloc

Pousser un bloc sans code complexe

Ce script rend un bloc poussable par le joueur en utilisant directement le moteur physique de Roblox, sans avoir besoin de code complexe pour détecter les contacts. part.Anchored = false est la ligne essentielle : elle « détache » la Part du monde et lui permet de bouger sous l’effet de forces physiques (comme la poussée du joueur). part.CanCollide = true garantit que le joueur ne traverse pas le bloc mais rentre réellement dedans, ce qui déclenche la poussée physique naturelle.

PhysicalProperties.new(...) personnalise le comportement physique du bloc : ici, une densité basse (0.2) rend l’objet léger et facile à pousser, une friction basse (0.2) le fait glisser facilement, et une élasticité (0.5) lui donne un léger effet de rebond.

part.CustomPhysicalProperties = physicalProperties applique ces réglages personnalisés à la Part, plutôt que d’utiliser les valeurs par défaut de Roblox (qui donneraient un objet plus lourd et moins glissant).

local part = script.Parent

local physicalProperties = PhysicalProperties.new(
	0.2,  -- Density (densité, plus c'est bas plus c'est léger à pousser)
	0.2,  -- Friction
	0.5,  -- Elasticity
	1,    -- FrictionWeight
	1     -- ElasticityWeight
)

part.Anchored = false
part.CanCollide = true
part.CustomPhysicalProperties = physicalProperties

Pousser un bloc avec une impulsion

Ce script combine deux mécanismes pour rendre un bloc poussable :

  1. Configuration physique de base : le bloc devient mobile (Anchored = false) et reçoit des propriétés physiques personnalisées (densité, friction, élasticité) qui définissent son comportement naturel (léger/lourd, glissant/collant, rebondissant ou non).
  2. Poussée scriptée additionnelle : en plus de la physique naturelle, le script détecte quand un joueur touche le bloc et lui applique une impulsion (un « coup de pousse ») dans la direction où le joueur regarde/avance, grâce à ApplyImpulse.

Détail du fonctionnement

  • humanoidRootPart.CFrame.LookVector récupère un vecteur représentant la direction vers laquelle le joueur est orienté — c’est cette direction qui détermine le bloc va être poussé.
  • part:ApplyImpulse(direction * PUSH_FORCE * part:GetMass()) calcule la force de poussée en tenant compte de la masse du bloc (GetMass()) : plus le bloc est lourd, plus il faut une impulsion importante pour le déplacer de la même façon (comme dans la vraie vie).
  • part.Touched:Connect(onTouched) signifie que cette poussée se déclenche à chaque fois que quelque chose touche le bloc — donc potentiellement plusieurs fois par seconde si le joueur reste collé dessus.

Pourquoi combiner les deux mécanismes ?

La physique seule (Anchored = false + CanCollide = true) suffit déjà à rendre le bloc poussable naturellement. Mais ajouter une impulsion scriptée permet de renforcer ou contrôler cet effet — par exemple pour que la poussée soit plus franche et immédiate, même si le joueur touche le bloc à faible vitesse.

QCM pour mieux comprendre

1. Que se passe-t-il si on met part.Anchored = true dans ce script ?
A. Le bloc devient plus facile à pousser
B. Le bloc ne pourra plus bouger du tout, malgré l’impulsion appliquée
C. Le bloc disparaît
D. Rien ne change

2. Que représente humanoidRootPart.CFrame.LookVector ?
A. La vitesse du joueur
B. La direction vers laquelle le joueur regarde/avance
C. La position exacte du joueur
D. Le nom du joueur

3. Pourquoi multiplie-t-on la force par part:GetMass() ?
A. Pour que la poussée soit toujours la même, peu importe le poids du bloc
B. Pour adapter la force de poussée au poids réel du bloc (plus lourd = plus de force nécessaire)
C. Pour calculer la vitesse du joueur
D. Pour rendre le bloc invisible

4. Que fait part:ApplyImpulse(...) ?
A. Il déplace instantanément le bloc à une position précise
B. Il applique une force ponctuelle qui pousse le bloc dans une direction donnée
C. Il détruit le bloc
D. Il change la couleur du bloc

5. Quand la fonction onTouched se déclenche-t-elle ?
A. Une seule fois au démarrage du jeu
B. À chaque fois qu’un objet (joueur ou autre) touche le bloc
C. Uniquement quand le joueur saute sur le bloc
D. Toutes les 5 secondes automatiquement

6. Si on augmente la valeur de PUSH_FORCE, que se passe-t-il ?
A. Le bloc devient plus lourd visuellement
B. Le bloc sera poussé plus fort/plus loin à chaque contact
C. Le joueur devient plus rapide
D. Rien, cette variable n’est pas utilisée dans le script

7. Pourquoi le script vérifie-t-il if not humanoid or not humanoidRootPart then return end ?
A. Pour vérifier que c’est bien un joueur (ou personnage) qui touche le bloc, et pas un autre objet
B. Pour supprimer le joueur s’il n’a pas de vie
C. Pour ralentir le jeu volontairement
D. Ce n’est pas nécessaire, cette ligne ne sert à rien

local part = script.Parent

local physicalProperties = PhysicalProperties.new(
	0.5,  -- Density (densité, plus c'est bas plus c'est léger à pousser)
	0.5,  -- Friction
	0.5,  -- Elasticity
	1,    -- FrictionWeight
	1     -- ElasticityWeight
)

part.Anchored = false
part.CanCollide = true
part.CustomPhysicalProperties = physicalProperties

local PUSH_FORCE = 2 -- Intensité de la poussée

local function onTouched(hit)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
	if not humanoid or not humanoidRootPart then return end

	-- Calcule la direction dans laquelle le joueur se déplace
	local direction = humanoidRootPart.CFrame.LookVector

	-- Applique une impulsion dans cette direction
	part:ApplyImpulse(direction * PUSH_FORCE * part:GetMass())
end

part.Touched:Connect(onTouched)

Pousser plusieurs BLOCs

local partFolder = script.Parent

local physicalProperties = PhysicalProperties.new(
	0.5,  -- Density (densité, plus c'est bas plus c'est léger à pousser)
	0.5,  -- Friction
	0.5,  -- Elasticity
	1,    -- FrictionWeight
	1     -- ElasticityWeight
)


local PUSH_FORCE = 20 -- Intensité de la poussée

local function onTouched(hit, part)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
	if not humanoid or not humanoidRootPart then return end

	-- Calcule la direction dans laquelle le joueur se déplace
	local direction = humanoidRootPart.CFrame.LookVector

	-- Applique une impulsion dans cette direction
	part:ApplyImpulse(direction * PUSH_FORCE * part:GetMass())
end

for _, part in partFolder:GetChildren() do
	if part:IsA("BasePart") then
		
		part.Anchored = false
		part.CanCollide = true
		part.CustomPhysicalProperties = physicalProperties		
		part.Touched:Connect(onTouched, part)
	end
end