Dopo aver creato alcuni script, non passa mai molto tempo prima di voler riutilizzare del codice tra di essi.A seconda di luogo, ModuleScripts ti consente di riutilizzare il codice tra gli script su lati diversi del confine client-server o sullo stesso lato del confine.
Puoi mettere gli script del modulo ovunque tu metta gli script, ma ReplicatedStorage è una posizione popolare; memorizzare gli script del modulo qui ti consente di riutilizzare il codice tra il server e i client.
Anatomia di uno script del modulo
In Roblox Studio, aggiungi uno script del modulo a ReplicatedStorage e rinominalo in PickupManager. Ogni ModuleScript inizia con il seguente codice:
local module = {}return module
Questo codice crea una tabella Luau vuota e la restituisce a qualsiasi script che richieda lo script del modulo.
Il valore di restituzione può essere qualsiasi tipo di dati ad eccezione di nil , ma la maggior parte degli script dei moduli restituisce una funzione, una tabella o una tabella di funzioni.Per generare il suo valore di ritorno, gli script del modulo possono ovviamente eseguire codice arbitrario, che include il richiedere altri script del modulo.
L'esempio seguente restituisce una tabella con una singola funzione chiamata getPickupBonus. Incollalo nello script del nuovo modulo:
-- ModuleScript nel ReplicatedStorage
local PickupManager = {}
local defaultMultiplier = 1.25
local rarityMultipliers = {
common = 10,
uncommon = 20,
rare = 50,
legendary = 100
}
-- Aggiungi la funzione getPickupBonus alla tabella PickupManager
PickupManager.getPickupBonus = function(rarity)
local bonus = rarityMultipliers[rarity] * defaultMultiplier
return bonus
end
return PickupManager
Aggiungere la funzione a una tabella non è strettamente necessario—puoi semplicemente restituire la funzione stessa—ma è un buon modello da Seguire; ti dà una sintassi facile da comprendere quando chiami la funzione da un altro script e ti consente di aggiungere facilmente più funzioni allo script del modulo nel tempo.
Richiedi gli script del modulo
Per caricare uno script del modulo, chiami la funzione require().In ReplicatedStorage , aggiungi un nuovo script e cambia il suo RunContext in Client .Quindi aggiungi il seguente codice per chiamare la funzione PickupManager.getPickupBonus :
Script del client nel ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Ottieni il valore restituito dal ModuleScriptlocal PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))-- Chiama una funzione ModuleScriptlocal bonus = PickupManager.getPickupBonus("legendary")print(bonus) --> 125
Il salvataggio degli script del modulo in ReplicatedStorage ti consente di condividere il codice tra il server e il client, in modo da poter utilizzare lo stesso codice per richiedere lo script da ServerScriptService :
Script nel ServerScriptService
local ReplicatedStorage = game:GetService("ReplicatedStorage")local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))
Quando chiami require() su un ModuleScript, esegue una volta e restituisce un singolo elemento come riferimento.Chiamare di nuovo restituisce esattamente la stessa referenza, il che significa che se modifichi una tabella restituita o , le successive chiamate restituiscono quella referenza modificata.Il modulo stesso non viene eseguito più volte.
Se richiedi un ModuleScript da entrambi i lati del confine client-server, come nell'esempio sopra, il ModuleScript restituisce un riferimento univoco per ciascun lato.
Modelli
Gli script dei moduli hanno alcuni modelli comuni che puoi utilizzare per semplificare il tuo codice e evitare trappole mentre la tua esperienza cresce in dimensioni e complessità.
Condivisione dei dati
Per associare i dati a oggetti individuali, puoi assegnare loro attributi o creare Configuration cartelle con oggetti di valore come StringValue o IntValue.Tuttavia, entrambi gli approcci sono problematici se vuoi aggiungere o modificare dozzine di oggetti o valori di dati.Inoltre non memorizzano tabelle o funzioni.
Se vuoi modificare gli stessi dati per più copie dello stesso oggetto o riutilizzare gli stessi dati per oggetti diversi, memorizza i dati in ModuleScripts .È un modo più semplice per riutilizzare i dati in altri script e puoi archiviare tabelle e funzioni.
L'esempio seguente ModuleScript in ReplicatedStorage memorizza i valori di configurazione per un'arma generica:
ModuleScript nel ReplicatedStorage
local GunConfig = {}GunConfig.MagazineSize = 20GunConfig.AmmoCount = 100GunConfig.Firerate = 600GunConfig.Damage = {["Head"] = 50;["Torso"] = 40;["Body"] = 25;}return GunConfig
Eventi personalizzati
Gli eventi personalizzati consentono agli script di comunicare tra loro, ma dover tenere traccia dei riferimenti a oggetti individuali BindableEvent può ingombrare il tuo codice.
Puoi usare ModuleScripts per memorizzare BindableEvents e fornire gestori di eventi personalizzati che sono direttamente legati ai metodi di ModuleScript .
Il seguente ModuleScript in ReplicatedStorage ha un evento personalizzato che si attiva quando l'interruttore cambia stato:
ModuleScript nel ReplicatedStorage
local Switch = {}
-- Creazione di legami in modo che qualsiasi script possa ascoltare quando l'interruttore è stato cambiato
local bindableEvent = Instance.new("BindableEvent")
Switch.Changed = bindableEvent.Event
local state = false
function Switch.flip()
state = not state
bindableEvent:Fire(state)
end
return Switch
Lo script cliente seguente in ReplicatedStorage connette una funzione da chiamare quando si attiva l'evento Switch.Changed.
Script nel ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Switch = require(ReplicatedStorage:WaitForChild("Switch"))
Switch.Changed:Connect(function(newState)
print("Switch state is now", newState)
end
-- Prova a capovolgere più volte
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()
Incapsulamento
L'incapsulamento è la pratica di creare uno strato di astrazione attorno agli oggetti o alla logica di scripting per nascondere la complessità.Puoi usare ModuleScripts per incapsulare gli oggetti Roblox con funzioni Luau personalizzate per semplificare il codice.
Ad esempio, puoi usare l'incapsulamento per:
- Semplifica la comunicazione tra reti con un singolo oggetto RemoteEvent .
- Avvolgi il codice di gestione degli errori attorno ai servizi sensibili come DataStoreService .
- Definisci metodi personalizzati per controllare o estendere le funzionalità dell'oggetto Roblox.
È difficile tenere traccia di dozzine di oggetti individuali RemoteEvent per implementare la rete nel tuo Gioco.Puoi usare un ModuleScript per incapsulare un singolo RemoteEvent per aiutare a semplificare questo problema.Includendo un argomento univoco id , puoi ancora inviare diversi messaggi di rete mentre usi solo un singolo RemoteEvent .
Nell'esempio seguente, il ModuleScript chiamato NetworkManagerClient incapsula il metodo RemoteEvent:FireServer() per includere questo argomento extra id .Inoltre, questo ModuleScript fa riferimento all'oggetto RemoteEvent stesso in modo che tu non debba farvi riferimento in altre parti del tuo codice.Devi solo richiedere questo ModuleScript per inviare messaggi di rete e non devi occuparti di oggetti RemoteEvent nell'intero resto del tuo codebase.
Il seguente ModuleScript in ReplicatedFirst fornisce una funzione incapsulata che puoi chiamare sui tuoi script client per inviare un Messaggiodi rete:
Modulo di rete
-- ModuleScript in ReplicatedFirst chiamato NetworkManagerClient
local NetworkManagerClient = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
-- Incapsulamento della funzione FireServer del oggetto remoto
function NetworkManagerClient.FireServer(id, ...)
remoteEvent:FireServer(id, ...)
end
return NetworkManagerClient
Il seguente ModuleScript in ServerScriptService utilizza BindableEvents per ogni script per connettersi a un ID specifico.Quando un client invia un Messaggiodi rete, ogni BindableEvent associato all'ID specificato scatta.
-- ModuleScript in ServerScriptService chiamato NetworkManagerServer
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- Collegare il nuovo BindableEvent all'id
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- Connessione a
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- Trovare ogni evento legabile che corrisponde all'ID dell'evento remoto ricevuto
for _, signal in networkSignalList do
if signal.id == id then
signal.bindableEvent:Fire(player, ...)
end
end
end)
return NetworkManagerServer
Il seguente LocalScript invia un messaggio con l'ID RequestA con un argomento opzionale Hello.
-- LocalScript nel ReplicatedFirstlocal ReplicatedFirst = game:GetService("ReplicatedFirst")local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))NetworkManagerClient.FireServer("RequestA", "Hello")
Il seguente Script si connette all'ID del messaggio di rete RequestA e stampa una dichiarazione con tutti i parametri aggiuntivi quando riceve la Richiesta.
-- Script nel ServerScriptService
local ServerScriptService = game:GetService("ServerScriptService")
local NetworkManagerServer = require(ServerScriptService:WaitForChild("NetworkManagerServer"))
NetworkManagerServer.GetServerEventSignal("RequestA"):Connect(function(player, ...)
print("Received RequestA from", player, ...)
end)