Objets & Physique

Objectif : Maîtriser le moteur physique de Roblox, créer des ambiances immersives et apprendre à cloner des objets dynamiquement. Ton monde va prendre vie !

Un Monde qui Réagit

Physique, sons et effets visuels

Un bon jeu, c'est plus que du code. C'est une ambiance ! Des objets qui tombent, des sons qui immergent, de la lumière qui met en valeur. Dans ce module, tu vas transformer ton monde statique en univers vivant.

1. Physique & Collisions

Roblox possède un moteur physique intégré. Les objets peuvent tomber, rebondir, glisser... si tu le configures correctement.

1.1 Les Propriétés Physiques Clés

Anchored

true = L'objet est "cloué" dans le vide. Aucune force ne peut le bouger.

false = L'objet subit la gravité et les collisions.

part.Anchored = false -- Tombe !
CanCollide

true = Les objets se cognent contre lui (solide).

false = Les objets passent à travers (fantôme).

part.CanCollide = false -- Traversable
Massless

true = L'objet n'a pas de masse (utile pour les accessoires).

N'affecte pas le poids d'un personnage qui le porte.

accessoire.Massless = true
CustomPhysicalProperties

Permet de définir la densité, friction, élasticité personnalisées.

part.CustomPhysicalProperties = PhysicalProperties.new(0.5, 0.3, 0.8)

1.2 Les Groupes de Collision

Tu peux créer des groupes pour contrôler quels objets se cognent entre eux. Par exemple : les balles des joueurs ne se touchent pas entre elles.

Configurer les groupes de collision

local PhysicsService = game:GetService("PhysicsService")

-- Créer les groupes
PhysicsService:RegisterCollisionGroup("Joueurs")
PhysicsService:RegisterCollisionGroup("Balles")

-- Définir les règles : Balles ne collisionnent pas entre elles
PhysicsService:CollisionGroupSetCollidable("Balles", "Balles", false)

-- Assigner un objet à un groupe
maBalle.CollisionGroup = "Balles"

Cas d'Usage Courant

Joueur vs Joueur : Désactive les collisions pour éviter que les joueurs se poussent.
Projectiles : Les balles traversent leur tireur mais touchent les ennemis.

2. Créer une Ambiance

L'ambiance d'un jeu passe par la lumière et le son. Roblox te donne tous les outils pour créer des atmosphères uniques.

2.1 Le Service Lighting

Le service Lighting contrôle l'éclairage global de ton jeu.

Modifier l'éclairage

local Lighting = game:GetService("Lighting")

-- Changer l'heure (0-24)
Lighting.ClockTime = 20  -- 20h = Nuit

-- Ambiance colorée
Lighting.Ambient = Color3.fromRGB(50, 50, 100)  -- Teinte bleutée

-- Brouillard mystérieux
Lighting.FogStart = 0
Lighting.FogEnd = 200
Lighting.FogColor = Color3.fromRGB(150, 150, 150)

2.2 Les Effets Visuels

Tu peux ajouter des effets post-processing dans Lighting :

Bloom

Effet de brillance autour des lumières

Blur

Flou pour les menus ou cinématiques

ColorCorrection

Modifier les couleurs globales

DepthOfField

Profondeur de champ cinématique

2.3 Le Service SoundService

Les sons ajoutent une dimension immersive. Tu peux jouer des sons depuis n'importe où :

Jouer un son

-- Créer un son
local son = Instance.new("Sound")
son.SoundId = "rbxassetid://123456789"  -- ID du son
son.Volume = 0.5
son.Parent = workspace

-- Jouer le son
son:Play()

-- Son en boucle (musique d'ambiance)
son.Looped = true
son:Play()
🎵 Trouver des Sons

Va dans la Toolbox de Roblox Studio, onglet "Audio". Tu peux chercher des sons gratuits ou uploader les tiens. Copie l'ID du son pour l'utiliser dans ton code.

3. Le Clonage (:Clone())

Plutôt que de créer des objets à partir de rien, tu peux dupliquer un modèle existant. C'est LA technique pour spawner des ennemis, objets, projectiles...

3.1 La Méthode :Clone()

Cloner un objet

-- L'original est stocké dans ServerStorage (invisible aux joueurs)
local template = game.ServerStorage:WaitForChild("Zombie")

-- Créer une copie
local nouveauZombie = template:Clone()

-- Positionner la copie
nouveauZombie:SetPrimaryPartCFrame(CFrame.new(0, 10, 0))

-- L'ajouter au monde (sinon il n'existe pas vraiment)
nouveauZombie.Parent = workspace
Où Stocker les Templates ?

ServerStorage ? Pour les objets serveur (ennemis, drops)
ReplicatedStorage ? Pour les objets partagés client/serveur

3.2 Spawner Automatique

Combine le clonage avec une boucle pour créer un spawner :

Spawner de pièces

local pieceTemplate = game.ServerStorage:WaitForChild("Piece")

local function spawnerPiece(position)
    local nouvellePiece = pieceTemplate:Clone()
    nouvellePiece.Position = position
    nouvellePiece.Parent = workspace
    
    -- Optionnel : Faire tourner la pièce
    nouvellePiece.Orientation = Vector3.new(0, math.random(0, 360), 0)
    
    return nouvellePiece
end

-- Spawner 10 pièces à des positions aléatoires
for i = 1, 10 do
    local posAleatoire = Vector3.new(
        math.random(-50, 50),
        5,
        math.random(-50, 50)
    )
    spawnerPiece(posAleatoire)
end

print("10 pièces ont été spawnées !")

3.3 Détruire un Clone

N'oublie pas de nettoyer les objets dont tu n'as plus besoin avec :Destroy() :

local piece = pieceTemplate:Clone()
piece.Parent = workspace

-- Après 10 secondes, la pièce disparaît
task.wait(10)
piece:Destroy()

print("La pièce a disparu !")
💻 Sandbox Luau
Simulateur v2.0
1 2 3 4 5 6 7 8 9 10
👉 Clique sur Exécuter pour tester ton code...

Quiz : Objets & Physique

5 questions pour valider tes acquis

1. Quelle propriété empêche un objet de tomber ?

  • CanCollide = true
  • Anchored = true
  • Massless = true
  • Locked = true

2. Quel service contrôle l'éclairage global ?

  • SoundService
  • Lighting
  • Workspace
  • ReplicatedStorage

3. Quelle méthode permet de dupliquer un objet ?

  • :Copy()
  • :Duplicate()
  • :Clone()
  • :Spawn()

4. Où stocke-t-on les templates d'objets côté serveur ?

  • Workspace
  • ServerStorage
  • StarterPack
  • Players

5. Quelle méthode supprime définitivement un objet ?

  • :Remove()
  • :Delete()
  • :Destroy()
  • :Kill()
Exercice Pratique

Configure la Boucle

Place les éléments dans le bon ordre pour créer une boucle for qui compte de 1 à 5 !

15-50 Points
task.wait(1)
Pause 1 seconde
for i = 1, 5 do
Début de boucle
end
Ferme la boucle
print(i)
Affiche le compteur
1
Initialisation...
2
Action principale...
3
Temporisation...
4
Clôture...
🚨
Étape 5/10

Système d'Alarme

Quand l'énergie devient critique (<20%), l'alarme clignote pour t'avertir. Tu as 30 secondes pour agir sinon... Game Over !

1
2
3
4
5
6
7
8
9
10
Prérequis

Modules 1 à 4 complétés (variables, conditions, boucles)

Construction du Système d'Alarme

1
Crée les Lumières d'Alarme

Crée 3 ou 4 Parts rouges pour les gyrophares.

Size2, 2, 2
ShapeBall (sphère)
MaterialNeon
ColorReally red
Nom"Alarme1", "Alarme2", etc.
2
Script de Clignotement

Ajoute ce script à une des alarmes :

local alarme = script.Parent
local estAllumee = true

-- Boucle infinie pour le clignotement
while true do
    if estAllumee then
        -- Allumer
        alarme.Material = Enum.Material.Neon
        alarme.Transparency = 0
    else
        -- Éteindre
        alarme.Material = Enum.Material.SmoothPlastic
        alarme.Transparency = 0.5
    end
    
    estAllumee = not estAllumee -- Inverse l'état
    task.wait(0.5) -- Clignote toutes les 0.5 secondes
end
3
Boucle avec Compteur

Modifie pour que l'alarme clignote 10 fois puis s'arrête :

local alarme = script.Parent

print("🚨 ALERTE DÉCLENCHÉE !")

-- Boucle for : clignote exactement 10 fois
for i = 1, 10 do
    -- Allumer
    alarme.Material = Enum.Material.Neon
    alarme.Transparency = 0
    task.wait(0.3)
    
    -- Éteindre
    alarme.Material = Enum.Material.SmoothPlastic
    alarme.Transparency = 0.5
    task.wait(0.3)
    
    print("Clignotement " .. i .. "/10")
end

print("? Alerte terminée")
alarme.Transparency = 1 -- Cache l'alarme
Bonus : Son d'Alarme

Ajoute un Sound dans l'alarme et joue-le dans la boucle avec sound:Play() pour un effet encore plus immersif !

🎉

Système d'alarme opérationnel !

Prochaine étape ? Module 6 : Portes Automatiques

💎
🚀 SURVIE SPATIALE - Étape 5/10

Zone de Collecte de Ressources

Les astéroïdes proches contiennent des 💎 Cristaux d'énergie. Crée un système de collecte avec physique, clones et destruction !

1
2
3
4
5
6
7
8
9
10
Rappel : Ta station a maintenant un Hub, une Salle de Contrôle, un Sas intelligent et un Réacteur. Les ressources sont nécessaires pour recharger le réacteur et survivre !
1
📐 Architecture de la Zone de Collecte

Crée une nouvelle zone à l'extérieur de la station, accessible par le Sas. Voici la structure dans Workspace :

▼ Workspace
📦 Station (existant)
▼ 📦 ZoneCollecte (nouveau!)
🧱 Plateforme
▼ 📂 Cristaux
💎 Cristal (template)
📜 SpawnerCristaux
▼ 📂 ReplicatedStorage
💎 CristalTemplate
2
🏗️ Créer la Plateforme Spatiale

Crée une plateforme métallique où les cristaux apparaîtront. Place-la à côté du Sas (dans l'espace !) :

NamePlateforme
Size40, 2, 40
MaterialDiamondPlate
Color[60, 60, 70]
Anchored
Position : Place la plateforme à environ 15 studs du Sas, comme si c'était une zone d'atterrissage extérieure !
3
💎 Créer le Template de Cristal

Crée un cristal d'énergie qui sera cloné par le script. Place-le dans ReplicatedStorage :

NameCristalTemplate
ShapeBall
Size2, 2, 2
MaterialNeon
Color[0, 255, 200]
Anchored✗ (false)
CanCollide

Ajoute une PointLight dans le cristal pour l'effet brillant :

Brightness1.5
Range8
Color[0, 255, 200]
Pourquoi ReplicatedStorage ?
Les objets dans ReplicatedStorage ne sont pas visibles dans le jeu mais peuvent être clonés par script. C'est parfait pour les templates !
4
📜 Script SpawnerCristaux

Crée un Script dans la ZoneCollecte qui fait apparaître des cristaux aléatoirement sur la plateforme :

-- SpawnerCristaux.lua -- Fait apparaître des cristaux d'énergie local ReplicatedStorage = game:GetService("ReplicatedStorage") local template = ReplicatedStorage:WaitForChild("CristalTemplate") local plateforme = script.Parent:WaitForChild("Plateforme") -- Configuration local SPAWN_INTERVAL = 5 -- Secondes entre chaque spawn local MAX_CRISTAUX = 10 -- Maximum de cristaux simultanés -- FONCTION : Générer une position aléatoire sur la plateforme local function getPositionAleatoire() local pos = plateforme.Position local size = plateforme.Size local x = pos.X + math.random(-size.X/2 + 2, size.X/2 - 2) local z = pos.Z + math.random(-size.Z/2 + 2, size.Z/2 - 2) local y = pos.Y + size.Y/2 + 10 -- Spawn au-dessus return Vector3.new(x, y, z) end -- FONCTION : Compter les cristaux existants local function compterCristaux() local count = 0 for _, obj in pairs(workspace:GetDescendants()) do if obj.Name == "Cristal" then count = count + 1 end end return count end -- FONCTION : Faire apparaître un cristal local function spawnCristal() if compterCristaux() >= MAX_CRISTAUX then print("⚠️ Maximum de cristaux atteint!") return end -- Clone le template local cristal = template:Clone() cristal.Name = "Cristal" cristal.Position = getPositionAleatoire() cristal.Parent = workspace print("💎 Cristal apparu!") end -- BOUCLE PRINCIPALE : Spawn régulier while true do spawnCristal() task.wait(SPAWN_INTERVAL) end
Concepts du cours appliqués :
Clone() → Duplique un objet
math.random() → Génère des positions aléatoires
Anchored = false → Les cristaux tombent avec la gravité !
GetDescendants() → Parcourt tous les objets
5
🎮 Script de Collecte (Touched)

Ajoute ce script dans le CristalTemplate (avant de le mettre dans ReplicatedStorage) pour qu'il soit collecté au toucher :

-- CollecteCristal.lua (dans le CristalTemplate) local cristal = script.Parent local dejaCollecte = false -- Quand un joueur touche le cristal cristal.Touched:Connect(function(touche) -- Vérifie si c'est un joueur local joueur = game.Players:GetPlayerFromCharacter(touche.Parent) if joueur and not dejaCollecte then dejaCollecte = true -- Empêche double collecte print("💎", joueur.Name, "a collecté un cristal!") -- Effet visuel : rétrécit avant destruction for i = 1, 5 do cristal.Size = cristal.Size * 0.7 cristal.Transparency = cristal.Transparency + 0.15 task.wait(0.05) end -- Détruit le cristal cristal:Destroy() end end)
Important : Le script doit être dans le template avant de le déplacer dans ReplicatedStorage, sinon les clones n'auront pas le script !
6
🎮 Tester le Système

Lance le jeu avec F5 et observe :

  • 💎 Des cristaux apparaissent toutes les 5 secondes
  • ⬇️ Ils tombent grâce à la physique (Anchored = false)
  • ✨ Au toucher, ils rétrécissent et disparaissent
  • 📊 Maximum 10 cristaux simultanés
Regarde l'Output pour voir les messages de collecte !
Bonus : Connecte au Réacteur !

Modifie le script de collecte pour ajouter de l'énergie au réacteur quand un cristal est collecté :

  • Utilise BindableEvent pour communiquer entre scripts
  • Chaque cristal donne +10 énergie au réacteur
  • Ajoute un Sound de collecte satisfaisant !
Indice : Tu peux stocker l'énergie dans une IntValue nommée "Energie" dans le Réacteur, puis la modifier depuis n'importe quel script !
💎

Zone de collecte opérationnelle !

Tu maîtrises maintenant le clonage, la physique et la destruction ! → Module 6 : Sauvegarde des ressources avec DataStore