Reutiliser le code

*Ce contenu est traduit en utilisant l'IA (Beta) et peut contenir des erreurs. Pour consulter cette page en anglais, clique ici.

Après avoir créé quelques scripts, il n'est jamais long avant que vous souhaitiez réutiliser du code entre eux.En fonction de l'emplacement, ModuleScripts vous permet de réutiliser du code entre les scripts sur différents côtés de la frontière client-serveur ou du même côté de la frontière.

Vous pouvez mettre les scripts de module n'importe où que vous mettez des scripts, mais ReplicatedStorage est un emplacement populaire ; le stockage des scripts de module ici vous permet de réutiliser le code entre le serveur et les clients.

Anatomie d'un script de module

Dans Roblox Studio, ajoutez un script de module à ReplicatedStorage et renommez-le en PickupManager. Chaque ModuleScript commence par le code suivant :


local module = {}
return module

Ce code crée une table Luau vide et la renvoie à tout script qui nécessite le script du module.

La valeur de retour peut être n'importe quel type de données excepté nil, mais la plupart des scripts de module retournent une fonction, une table ou une table de fonctions.Pour générer sa valeur de retour, les scripts de module peuvent bien sûr exécuter du code arbitraire, qui inclut la nécessité d'autres scripts de module.

L'exemple suivant renvoie une table avec une seule fonction appelée getPickupBonus. Insérez-la dans le script du nouveau module :


-- ModuleScript dans ReplicatedStorage
local PickupManager = {}
local defaultMultiplier = 1.25
local rarityMultipliers = {
common = 10,
uncommon = 20,
rare = 50,
legendary = 100
}
-- Ajoutez la fonction getPickupBonus à la table PickupManager
PickupManager.getPickupBonus = function(rarity)
local bonus = rarityMultipliers[rarity] * defaultMultiplier
return bonus
end
return PickupManager

Ajouter la fonction à une table n'est pas strictement nécessaire — vous pouvez simplement retourner la fonction elle-même — mais c'est un bon modèle à s'abonner; cela vous donne une syntaxe facile à comprendre lorsque vous appelez la fonction à partir d'un autre script et vous permet d'ajouter facilement plus de fonctions au script du module au fil du temps.

Exiger les scripts de module

Pour charger un script de module, vous appelez la fonction require().Dans ReplicatedStorage , ajoutez un nouveau script, et modifiez son RunContext en Client .Ensuite, ajoutez le code suivant pour appeler la fonction PickupManager.getPickupBonus :

Script client dans ReplicatedStorage

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Obtenez la valeur renvoyée par le ModuleScript
local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))
-- Appeler une fonction ModuleScript
local bonus = PickupManager.getPickupBonus("legendary")
print(bonus) --> 125

Le stockage des scripts de module dans ReplicatedStorage vous permet de partager du code entre le serveur et le client, afin que vous puissiez utiliser le même code pour exiger le script de ServerScriptService :

Script dans ServerScriptService

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))

Lorsque vous appelez require() sur un ModuleScript, il s'exécute une fois et renvoie un seul élément en tant que référence.Appeler à nouveau renvoie exactement la même référence, ce qui signifie que si vous modifiez une table renvoyée ou , les appels suivants renvoient cette référence modifiée.Le module lui-même ne s'exécute pas plusieurs fois.

Si vous avez besoin d'un ModuleScript de chaque côté de la frontière client-serveur, comme dans l'exemple ci-dessus, le ModuleScript retourne une référence unique pour chaque côté.

Motifs

Les scripts de module ont quelques modèles communs que vous pouvez utiliser pour simplifier votre code et éviter les pièges à mesure que votre expérience gagne en taille et en complexité.

Partage de données

Pour associer des données à des objets individuels, vous pouvez leur attribuer des attributs ou créer des dossiers Configuration avec des objets de valeur tels que StringValue ou IntValue .Cependant, les deux approches sont gênantes si vous voulez ajouter ou modifier des dizaines d'objets ou de valeurs de données.Ils ne stockent pas non plus de tables ou de fonctions.

Si vous voulez modifier les mêmes données pour plusieurs copies du même objet ou réutiliser les mêmes données pour différents objets, stockez les données dans ModuleScripts .C'est un moyen plus facile pour vous de réutiliser les données dans d'autres scripts, et vous pouvez stocker des tables et des fonctions.

L'exemple suivant ModuleScript dans ReplicatedStorage stocke les valeurs de configuration pour une arme générique :

ModuleScript dans ReplicatedStorage

local GunConfig = {}
GunConfig.MagazineSize = 20
GunConfig.AmmoCount = 100
GunConfig.Firerate = 600
GunConfig.Damage = {
["Head"] = 50;
["Torso"] = 40;
["Body"] = 25;
}
return GunConfig

Événements personnalisés

Les événements personnalisés permettent aux scripts de communiquer entre eux, mais le fait de devoir suivre les références à des objets individuels BindableEvent peut encombrer votre code.

Vous pouvez utiliser ModuleScripts pour stocker BindableEvents et fournir des gestionnaires d'événements personnalisés qui sont directement liés aux méthodes de ModuleScript.

Le suivant ModuleScript dans ReplicatedStorage a un événement personnalisé qui se déclenche lorsque le commutateur change d'état :

ModuleScript dans ReplicatedStorage

local Switch = {}
-- Créer des liens afin que tout script puisse écouter lorsque l'interrupteur a été modifié
local bindableEvent = Instance.new("BindableEvent")
Switch.Changed = bindableEvent.Event
local state = false
function Switch.flip()
state = not state
bindableEvent:Fire(state)
end
return Switch

Le script client suivant dans ReplicatedStorage connecte une fonction à appeler lorsque l'événement Switch.Changed se déclenche.

Script dans ReplicatedStorage

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Switch = require(ReplicatedStorage:WaitForChild("Switch"))
Switch.Changed:Connect(function(newState)
print("Switch state is now", newState)
end
-- Testez le retournement plusieurs fois
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()

Enfermement

L'encapsulation est la pratique de créer une couche d'abstraction autour d'objets ou de logique de script pour cacher la complexité.Vous pouvez utiliser ModuleScripts pour encapsuler les objets Roblox avec des fonctions Luau personnalisées pour simplifier le code.

Par exemple, vous pouvez utiliser l'encapsulation pour :

  • Simplifiez la communication entre réseaux avec un seul objet RemoteEvent .
  • Enveloppez le code de gestion des erreurs autour de services sensibles tels que DataStoreService .
  • Définissez des méthodes personnalisées pour contrôler ou étendre les fonctionnalités des objets Roblox.

Il est difficile de suivre des dizaines d'objets individuels RemoteEvent pour implémenter la mise en réseau dans votre jeu.Vous pouvez utiliser un ModuleScript pour encapsuler un seul RemoteEvent pour aider à simplifier ce problème.En incluant un argument unique id , vous pouvez toujours envoyer différents messages réseau tout en utilisant un seul RemoteEvent .

Dans l'exemple ci-dessous, le ModuleScript nommé NetworkManagerClient encapsule la méthode RemoteEvent:FireServer() pour inclure cet argument supplémentaire id.En outre, cette ModuleScript fait référence à l'objet RemoteEvent afin que vous n'ayez pas à le référencer dans d'autres parties du code.Vous n'avez besoin de cette exigence ModuleScript que pour envoyer des messages réseau et n'avez pas besoin de traiter avec RemoteEvent les objets dans le reste de votre base de code.

Le suivant ModuleScript dans ReplicatedFirst fournit une fonction encapsulée que vous pouvez appeler sur vos scripts clients pour envoyer un message réseau :

Module réseau

-- ModuleScript dans ReplicatedFirst nommé NetworkManagerClient
local NetworkManagerClient = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
-- Encapsulation de la fonction FireServer de l'objet distant
function NetworkManagerClient.FireServer(id, ...)
remoteEvent:FireServer(id, ...)
end
return NetworkManagerClient

Le suivant ModuleScript dans ServerScriptService utilise BindableEvents pour chaque script de se connecter à un ID spécifique.Lorsqu'un client envoie un message réseau, chaque BindableEvent associé à l'ID spécifié se déclenche.


-- ModuleScript dans ServerScriptService nommé NetworkManagerServer
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- Lier le nouvel événement liable à l'ID
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- Se connecter à
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- Trouver chaque événement bindable correspondant à l'ID de l'événement distant reçu
for _, signal in networkSignalList do
if signal.id == id then
signal.bindableEvent:Fire(player, ...)
end
end
end)
return NetworkManagerServer

Le message suivant LocalScript envoie un message avec l'ID RequestA avec un argument facultatif Hello.


-- LocalScript dans ReplicatedFirst
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))
NetworkManagerClient.FireServer("RequestA", "Hello")

Le suivant Script se connecte à l'ID de message réseau RequestA et imprime une déclaration avec tous les paramètres supplémentaires lorsqu'il reçoit la demande.


-- Script dans ServerScriptService
local ServerScriptService = game:GetService("ServerScriptService")
local NetworkManagerServer = require(ServerScriptService:WaitForChild("NetworkManagerServer"))
NetworkManagerServer.GetServerEventSignal("RequestA"):Connect(function(player, ...)
print("Received RequestA from", player, ...)
end)