Depois de criar alguns scripts, nunca é longo antes de você querer reutilizar alguns códigos entre eles. Dependendo de localização , ModuleScripts deixe você reutilizar códigos entre scripts em diferentes lados da fronteira cliente-servidor ou na mesma fronteira.
Criando Scripts de Módulo
Você pode colocar scripts de módulo em qualquer lugar que você colocar scripts, mas ReplicatedStorage é um local popular; armazenar scripts de módulo aqui permite que você reutilize o código entre o servidor e os clientes.
- Selecione ModuleScript para adicionar um novo script de módulo.
- Clique com o botão direito no script e renomeie-o para PickupManager.
- Clique duas vezes no script para abri-lo no Editor de Scripts.
Análise de um Script de Módulo
Cada ModuleScript começa com o seguinte código:
local module = {}return module
Este código cria uma tabela Luau vazia e retorna a qualquer script que exija o script de módulo.
O valor de retorno pode ser qualquer tipo de dado exceto nil, mas a maioria dos scripts de módulo retorna uma função, uma tabela ou uma tabela de funções. Para gerar seu valor de retorno, os scripts de módulo podem, claro, executar códigos arbitrários, que incluem a exigência de outros scripts de módulo.
O seguinte exemplo retorna uma tabela com uma única função chamada getPickupBonus. Cole-a em seu novo script de módulo:
-- ModuleScript em ReplicatedStorage
local PickupManager = {}
local defaultMultiplier = 1.25
local rarityMultipliers = {
common = 10,
uncommon = 20,
rare = 50,
legendary = 100
}
-- Adicione a função getPickupBonus à tabela PickupManager
PickupManager.getPickupBonus = function(rarity)
local bonus = rarityMultipliers[rarity] * defaultMultiplier
return bonus
end
return PickupManager
Adicionar a função a uma tabela não é estritamente necessário — você pode apenas retornar a função em si mesma —, mas é um bom padrão para seguir; ele dá a você uma linguagem fácil de entender quando você chama a função de outro script e permite que você adicione facilmente mais funções ao script do módulo ao longo do tempo.
Requerendo Scripts de Módulo
Para carregar um script de módulo, você chama a função require(). Em ReplicatedStorage, adicione um novo script e altere seu RunContext para 1> Client1>. Em seguida, adicione o seguinte código para chamar a função 4> PickupManager.getPickupBonus4>:
Script do cliente em ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Obtenha o valor retornado por ModuleScriptlocal PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))-- Chame uma função de ModuleScriptlocal bonus = PickupManager.getPickupBonus("legendary")print(bonus) --> 125
Você pode usar o mesmo código para exigir o script de ServerScriptService :
Script em ServerScriptStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Obtenha o valor de retorno para o ModuleScript chamado "PickupManager"local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))
Quando você chama require() em um ModuleScript, ele é executado uma única vez e retorna um único item como referência. Chamar require() novamente
Se você exigir um ModuleScript de ambos os lados da fronteira cliente-servidor, o ModuleScript retorna uma referência única para cada lado.
Padrões
Scripts de módulos têm alguns padrões comuns que você pode usar para simplificar seu código e evitar armadilhas à medida que sua experiência cresce em tamanho e complexidade.
Compartilhamento de Dados
Para associar dados a objetos individuais, você pode atribuir atributos a eles ou criar Configuration pastas com objetos de valor, como StringValue ou IntValue. No entanto, ambas as abordagens são problemáticas se você quiser adicionar ou modificar dezenas de objetos ou valores de dados. Eles também não armazenam tabelas ou funções.
Se você quiser modificar os mesmos dados para várias cópias do mesmo objeto ou reutilizar os mesmos dados para diferentes objetos, armazene os dados em ModuleScripts. É uma maneira mais fácil de reutilizar os dados em outros scripts e você pode armazenar tabelas e funções.
O seguinte exemplo ModuleScript em ReplicatedStorage armazena os valores de configuração para uma arma genérica:
ModuleScript em ReplicatedStorage
local GunConfig = {}GunConfig.MagazineSize = 20GunConfig.AmmoCount = 100GunConfig.Firerate = 600GunConfig.Damage = {["Head"] = 50;["Torso"] = 40;["Body"] = 25;}return GunConfig
Eventos Personalizados
Eventos personalizados permitem que scripts se comuniquem entre si, mas ter que acompanhar referências a objetos BindableEvent individuais pode desordenar seu código.
Você pode usar ModuleScripts to store BindableEvents and provide custom event handlers that are directly tied to the methods of ModuleScript .
O seguinte ModuleScript em ReplicatedStorage tem um evento personalizado que dispara quando o interruptor muda de estado:
ModuleScript em ReplicatedStorage
local Switch = {}
-- Criar um cabo vinculado para que qualquer script possa ouvir quando a alavanca for alterada
local bindableEvent = Instance.new("BindableEvent")
Switch.Changed = bindableEvent.Event
local state = false
function Switch.flip()
state = not state
bindableEvent:Fire(state)
end
return Switch
O seguinte script de cliente em ReplicatedStorage conecta uma função para ser chamada quando o evento Switch.Changed é disparado.
Script em ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Switch = require(ReplicatedStorage:WaitForChild("Switch"))
Switch.Changed:Connect(function(newState)
print("Switch state is now", newState)
end
-- Teste o flipping algumas vezes
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()
Encapsulamento
Encapsulamento é a prática de criar uma camada de abstração em torno de objetos ou lógica de script para ocultar a complexidade. Você pode usar ModuleScripts para encapsular objetos Roblox com funções Lua personalizadas para simplificar o código.
Por exemplo, você pode usar o encapsulamento para:
- Simplifique a comunicação entre redes com um único RemoteEvent Objeto.
- Wrap error handling code around sensitive services such as DataStoreService .
- Definir métodos personalizados para controlar ou expandir recursos de objetos Roblox.
É difícil acompanhar dezenas de objetos RemoteEvent individuais para implementar a rede no seu jogo. Você pode usar um ModuleScript para encapsular um único RemoteEvent para ajudar a simplificar esse problema. Ao incluir um argumento de 1> id
No exemplo abaixo, o ModuleScript chamado NetworkManagerClient encapsula o método Class
O seguinte ModuleScript em ReplicatedFirst fornece uma função encapsulada que você pode chamar em seus scripts de cliente para enviar uma mensagem de rede:
Módulo de Rede
-- ModuleScript em ReplicatedFirst chamado NetworkManagerClient
local NetworkManagerClient = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
-- Encapsulando a função do FireServer remoto
function NetworkManagerClient.FireServer(id, ...)
remoteEvent:FireServer(id, ...)
end
return NetworkManagerClient
O seguinte ModuleScript em ServerScriptService usa BindableEvents para que cada script se conecte a um ID específico. Quando um cliente envia uma mensagem de rede, cada 1> Class.BindableEvent1> associado ao ID especificado é acionado.
-- ModuleScript em ServerScript Serviço chamado NetworkManagerServer
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- Vinculando o novo BindableEvent ao id
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- Conectando ao
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- Encontrando todos os eventos vinculáveis que correspondem ao ID do evento remoto recebido
for _, signal in networkSignalList do
if signal.id == id then
signal.bindableEvent:Fire(player, ...)
end
end
end)
return NetworkManagerServer
O seguinte LocalScript envia uma mensagem com o ID RequestA com um argumento opcional Hello.
-- LocalScript em ReplicatedFirstlocal ReplicatedFirst = game:GetService("ReplicatedFirst")local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))NetworkManagerClient.FireServer("RequestA", "Hello")
O seguinte Script conecta-se ao ID de mensagem de rede RequestA e imprime uma declaração com quaisquer parâmetros adicionais quando recebe a solicitar / pedir.
-- Script em ServerScriptService
local ServerScriptService = game:GetService("ServerScriptService")
local NetworkManagerServer = require(ServerScriptService:WaitForChild("NetworkManagerServer"))
NetworkManagerServer.GetServerEventSignal("RequestA"):Connect(function(player, ...)
print("Received RequestA from", player, ...)
end)