Après avoir créé quelques scripts, il n'est jamais long avant que vous souhaitiez réutiliser du code entre eux. En fonction de lieu , ModuleScripts laissez-vous 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.
Créer des scripts de module
Vous pouvez mettre des 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.
- Dans Roblox Studio, passez la souris sur ReplicatedStorage dans la Explorateur fenêtre et cliquez sur + .
- Sélectionnez ModuleScript pour ajouter un nouveau script de module.
- Faites un clic droit sur le script et renommez-le en PickupManager.
- Double-cliquez sur le script pour l'ouvrir dans le Éditeur de scripts.
Anatomie d'un script de module
Chaque ModuleScript commence par le code suivant :
local module = {}return module
Ce code crée une table Luau vide et le renvoie à tout script qui nécessite le script de module.
La valeur de retour peut être n'importe quel type de données sauf 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, ce qui inclut la nécessité d'autres scripts de module.
L'exemple suivant renvoie une table contenant une seule fonction appelée getPickupBonus . Copiez-le dans votre nouveau script de 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 renvoyer la fonction elle-même — mais c'est un bon modèle à s'abonner; il 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 de module au fil du temps.
Exigeant des scripts de module
Pour charger un script de module, vous appelez la fonction require(). Dans ReplicatedStorage, ajoutez un nouveau script et changez son RunContext en 1> Client1>. Ensuite, ajoutez le code suivant pour appeler la fonction 4>PickupManager.getPickupBonus4> :
Script du client dans ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Obtenez la valeur renvoyée parModuleScriptlocal PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))-- Appeler une fonctionModuleScriptlocal bonus = PickupManager.getPickupBonus("legendary")print(bonus) --> 125
Vous pouvez utiliser le même code pour exiger le script à partir de ServerScriptService :
Script dans ServerScriptStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Obtenez la valeur de retour pour le ModuleScript nommé « PickupManager »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 require()
Si vous avez besoin d'un ModuleScript des deux côtés de la frontière client-serveur, le ModuleScript renvoie 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 grandit 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 Configuration dossiers avec des objets de valeur tels que StringValue ou IntValue . Cependant, les deux approches sont gênantes si vous voulez ajouter ou modifier des douzaines 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, storez 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 tableaux et des fonctions.
L'exemple suivant ModuleScript dans ReplicatedStorage stocke les valeurs de configuration pour un pistolet générique :
ModuleScript dans ReplicatedStorage
local GunConfig = {}GunConfig.MagazineSize = 20GunConfig.AmmoCount = 100GunConfig.Firerate = 600GunConfig.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 un lien pour que tout script puisse écouter quand le commutateur a été changé
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 flipping quelques fois
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()
Encapsulation
L'encapsulation consiste à créer une couche d'abstraction autour des objets ou de la logique de script pour masquer la complexité. Vous pouvez utiliser ModuleScripts pour encapsuler les objets Roblox avec des fonctions Lua personnalisées pour simplifier le code.
Par exemple, vous pouvez utiliser l'encapsulation pour :
- Simplifyez la communication entre réseaux avec un seul RemoteEvent objet.
- Wrap error handling code around sensitive services such as 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 RemoteEvent individuels 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 1> id
Dans l'exemple ci-dessous, le ModuleScript nommé NetworkManagerClient encapsule la méthode <
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 de 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 se connecter à un ID spécifique. Lorsqu'un client envoie un message réseau, chaque 1> Class.BindableEvent1> associé au 4> Class.ServerScriptService4> se déclenche.
-- ModuleScript dans ServerScriptService nommé NetworkManagerServer
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- Liaison du nouvel événement liable à l'ID
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- Connexion à
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- Rechercher tous les événements liables qui correspondent à l'identifiant 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 LocalScript suivant envoie un message avec l'ID RequestA avec un argument Hello facultatif.
-- LocalScript dans ReplicatedFirstlocal ReplicatedFirst = game:GetService("ReplicatedFirst")local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))NetworkManagerClient.FireServer("RequestA", "Hello")
Le Script suivant se connecte à l'identifiant du 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)