Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU01

Rétrécir puis restaurer la taille du joueur

A partir du tuto « Change la taille du joueur« 

Quand un joueur touche une partie (ScalePart), sa taille alterne entre :

  • Réduction (taille = SCALEMINI).
  • Restauration (taille d’origine).
  • Un cooldown (COOLDOWN) empêche le joueur de déclencher l’effet trop souvent.
  • Le script gère aussi les joueurs qui quittent le jeu pour éviter les fuites de mémoire.

Comprendre le but du script

But :

  • Créer une partie (ScalePart) qui, quand un joueur la touche, alterne sa taille (rétrécit → restaure → rétrécit…).
  • Limiter la fréquence avec un cooldown (2 secondes).
  • Nettoyer les données des joueurs qui quittent le jeu pour éviter les bugs.

Concepts clés :

  • Variables : SCALEMINI, COOLDOWN.
  • Tableaux associatifs : cooldowns (pour le cooldown) et savedScales (pour stocker la taille d’origine).
  • Événements : Touched (pour détecter le contact) et PlayerRemoving (pour nettoyer les données).
  • Conditions : Vérifier si le joueur est déjà réduit (if originalScale then ...).

À toi de jouer !

  1. Copie ce script dans un Script dans Roblox Studio (par exemple, dans ServerScriptService).
  2. Crée les éléments nécessaires :
    • Un dossier ScaleFolder dans Workspace.
    • Une partie (Part) nommée ScalePart dans ce dossier.
  3. Teste le jeu :
    • Lance le jeu et touche la ScalePart :
      • Ton personnage rétrécit à 0.3.
      • Attends 2 secondes et touche à nouveau : ta taille est restaurée.
      • Touche une 3ème fois : tu rétrécis à nouveau.
    • Teste avec 2 joueurs :
      • Vérifie que chaque joueur a son propre cooldown et sa propre taille sauvegardée.

Le script

Voici le script commenté pour comprendre chaque partie :

-- Services et objets nécessaires
local Players = game:GetService("Players")  -- Service pour gérer les joueurs

-- Récupérer la partie et son dossier parent
local folder = workspace:WaitForChild("ScaleFolder")  -- Dossier contenant la partie
local part = folder:WaitForChild("ScalePart")  -- La partie à toucher

-- Variables globales
local SCALEMINI = 0.3  -- Taille réduite appliquée au contact
local COOLDOWN = 2     -- Temps d'attente (en secondes) avant de pouvoir re-déclencher

-- Tableaux pour gérer les états des joueurs
local cooldowns = {}    -- [player] = true si le joueur est en cooldown
local savedScales = {} -- [player] = taille d'origine du joueur (si il est actuellement réduit)

-- Détecter quand un joueur touche la partie
part.Touched:Connect(function(hit)
    -- Trouver le personnage du joueur qui a touché la partie
    local character = hit:FindFirstAncestorOfClass("Model")
    local player = character and Players:GetPlayerFromCharacter(character)

    -- Ignorer si ce n'est pas un joueur (ex: un mob, un débris)
    if not player then return end

    -- VÉRIFIER LE COOLDOWN : Si le joueur est en cooldown, on arrête tout
    if cooldowns[player] then return end

    -- Trouver l'humanoïde du personnage (pour modifier sa taille)
    local humanoid = character:FindFirstChildOfClass("Humanoid")
    if not humanoid then return end

    -- ACTIVER LE COOLDOWN pour ce joueur
    cooldowns[player] = true

    -- Récupérer la taille d'origine du joueur (si elle a été sauvegardée)
    local originalScale = savedScales[player]
    local targetScale  -- Taille cible (soit SCALEMINI, soit la taille d'origine)

    -- LOGIQUE FLIP/FLOP :
    if originalScale then
        -- Le joueur est déjà réduit : on restaure sa taille d'origine
        targetScale = originalScale
        savedScales[player] = nil  -- Supprimer la taille sauvegardée
    else
        -- Le joueur n'est pas réduit : on sauvegarde sa taille et on l'applique SCALEMINI
        savedScales[player] = humanoid.BodyHeightScale.Value
        targetScale = SCALEMINI
    end

    -- Appliquer la taille cible au personnage
    humanoid.BodyHeightScale.Value = targetScale
    humanoid.BodyWidthScale.Value = targetScale
    humanoid.BodyDepthScale.Value = targetScale
    humanoid.HeadScale.Value = targetScale

    -- Après COOLDOWN secondes, réactiver la possibilité de déclencher l'effet
    task.delay(COOLDOWN, function()
        cooldowns[player] = nil
    end)
end)

-- NETTOYAGE : Quand un joueur quitte le jeu, supprimer ses données
Players.PlayerRemoving:Connect(function(player)
    cooldowns[player] = nil
    savedScales[player] = nil
end)

Explications détaillées

1. Le mécanisme de flip/flop

  • Principe :
    Le script alterne la taille du joueur entre :
    • Réduction (SCALEMINI = 0.3) quand il touche la partie pour la première fois.
    • Restauration (taille d’origine) quand il la touche à nouveau.
  • Comment ça marche ?
    • Le tableau savedScales stocke la taille d’origine du joueur uniquement quand il est réduit.
    • Si savedScales[player] existe (originalScale), cela signifie que le joueur est déjà réduit → on restaure sa taille.
    • Sinon, on sauvegarde sa taille actuelle et on applique SCALEMINI.
  • Exemple concret :
    • 1er contact : Le joueur a une taille normale (ex: 1.0). Le script sauvegarde 1.0 dans savedScales[player] et applique 0.3.
    • 2ème contact : Le script voit que savedScales[player] = 1.0 existe → il restaure la taille à 1.0 et supprime savedScales[player].
    • 3ème contact : savedScales[player] n’existe plus → le joueur est à nouveau réduit à 0.3.

2. Pourquoi un cooldown ?

  • Problème sans cooldown :
    Si un joueur touche la partie plusieurs fois en une seconde, sa taille changera trop vite (ex: rétrécir → restaurer → rétrécir en 0.1 seconde).
    Cela rendrait le jeu incontrôlable et peu amusant.
  • Solution avec cooldown :
    • cooldowns[player] = true bloque le joueur pendant COOLDOWN secondes (2 secondes ici).
    • Après ce délai, cooldowns[player] = nil permet au joueur de déclencher à nouveau l’effet.
  • Analogie :
    Imagine un interrupteur qui ne peut être actionné qu’une fois toutes les 2 secondes. Le cooldown, c’est comme ce délai de sécurité !

3. Pourquoi nettoyer les tableaux quand un joueur quitte ?

  • Problème sans nettoyage :
    Si un joueur quitte le jeu sans que ses données soient supprimées, les tableaux cooldowns et savedScales garderont des entrées inutiles.
    • Conséquences :
      • Fuites de mémoire : Les tableaux grossissent indéfiniment.
      • Bugs : Si un nouveau joueur rejoint avec le même player (rare mais possible), il pourrait hériter des données du joueur précédent.
  • Solution avec PlayerRemoving :luaCopierPlayers.PlayerRemoving:Connect(function(player) cooldowns[player] = nil savedScales[player] = nil end)
    • Quand un joueur quitte, on supprime ses entrées dans les deux tableaux.
    • Cela garantit que les tableaux restent propres et efficaces.
  • Analogie :
    C’est comme ranger ton bureau après avoir fini tes devoirs : si tu ne ranges pas, ton bureau devient un bordel, et tu ne retrouves plus rien !

4. Autres concepts importants

  • FindFirstAncestorOfClass("Model") :
    Permet de remonter dans la hiérarchie de l’objet touché (hit) pour trouver le personnage (qui est un Model).
    • Exemple : Si hit est un bras du personnage, FindFirstAncestorOfClass("Model") retourne le personnage entier.
  • task.delay(COOLDOWN, function() ... end) :
    Exécute une fonction après un délai (COOLDOWN secondes). Ici, on réinitialise le cooldown du joueur.
  • Tableaux associatifs :
    • cooldowns et savedScales utilisent les joueurs comme clés.
    • Exemple :luaCopiersavedScales = { [Player1] = 1.0, -- Player1 a une taille d'origine de 1.0 [Player2] = nil -- Player2 n'est pas réduit }

QCM pour vérifier la compréhension

Sur le flip/flop :

  1. Que fait le script quand un joueur touche la partie pour la première fois ?
    • a) Il rétrécit le joueur et sauvegarde sa taille d’origine.
    • b) Il restaure la taille du joueur.
    • c) Il supprime le joueur.
  2. Que fait le script quand un joueur touche la partie une deuxième fois ?
    • a) Il rétrécit le joueur.
    • b) Il restaure la taille d’origine du joueur.
    • c) Il ne fait rien.
  3. Pourquoi utilise-t-on savedScales[player] = nil quand on restaure la taille ?
    • a) Pour indiquer que le joueur n’est plus réduit.
    • b) Pour supprimer le joueur du jeu.
    • c) Pour accélérer le jeu.

Sur le cooldown :

  1. À quoi sert cooldowns[player] = true ?
    • a) À bloquer le joueur pendant COOLDOWN secondes.
    • b) À faire grandir le joueur.
    • c) À changer la couleur de la partie.
  2. Que se passe-t-il si on supprime if cooldowns[player] then return end ?
    • a) Le joueur peut déclencher l’effet plusieurs fois par seconde.
    • b) Le joueur ne peut plus jamais déclencher l’effet.
    • c) Le jeu plantera.

Sur le nettoyage des tableaux :

  1. Pourquoi nettoyer cooldowns et savedScales quand un joueur quitte ?
    • a) Pour éviter les fuites de mémoire et les bugs.
    • b) Pour faire planter le jeu.
    • c) Pour accélérer le jeu.
  2. Que fait Players.PlayerRemoving:Connect(function(player) ... end) ?
    • a) Il exécute une fonction quand un joueur quitte le jeu.
    • b) Il supprime tous les joueurs.
    • c) Il crée un nouveau joueur.

Sur les conditions :

  1. À quoi sert if originalScale then ... ?
    • a) À vérifier si le joueur est déjà réduit (et donc doit être restauré).
    • b) À vérifier si le joueur existe.
    • c) À changer la couleur du joueur.

2. Ajouter un effet sonore

  • Objectif : Jouer un son quand le joueur rétrécit ou est restauré.
  • Indice :
    Crée un objet Sound dans ReplicatedStorage, puis utilise sound:Play().
    Exemple :
local sound = Instance.new("Sound") sound.SoundId = "rbxassetid://123456789" -- Remplace par un vrai ID de son 
sound.Parent = character.Head 
sound:Play()

Résumé des concepts appris

ConceptExplicationExemple dans le script
VariablesStocker des valeurs (nombres, texte, etc.).SCALEMINI = 0.3, COOLDOWN = 2
Tableaux associatifsStocker des données liées à des clés (ex: joueurs).cooldowns[player] = true, savedScales[player] = 1.0
ÉvénementsRéagir à des actions (ex: toucher une partie, quitter le jeu).part.Touched:Connect, Players.PlayerRemoving:Connect
ConditionsExécuter du code seulement si une condition est vraie.if originalScale then ..., if cooldowns[player] then return end
Fonctions asynchronesExécuter du code après un délai.task.delay(COOLDOWN, function() ... end)
Nettoyage des donnéesSupprimer les données inutiles pour éviter les bugs.Players.PlayerRemoving:Connect(function(player) ... end)