Nachdem einige Skripte erstellt wurden, dauert es nie lange, bevor Sie einige Code zwischen ihnen wiederverwenden möchten. Abhängig von Ort , ModuleScripts lassen Sie Code zwischen Skripts auf verschiedenen Seiten der Client-Server-Grenze oder auf derselben Seite der Grenze wiederverwenden.
Modul-Skripte erstellen
Du kannst Modul-Skripte überall platzieren, wo du Skripte platzierst, aber ReplicatedStorage ist ein beliebter Ort; das Speichern von Modul-Skripten hier ermöglicht es dir, Code zwischen dem Server und Clients wiederzuverwenden.
- In Roblox Studio, bewegen Sie den Mauszeiger über ReplicatedStorage in dem Explorer-Fenster und klicken Sie auf + .
- Wähle ModuleScript , um ein neues Skript, das. PL: die Skriptshinzuzufügen.
- Klicken Sie mit der rechten Maustaste auf das Skript und benennen Sie es in PickupManager um.
- Doppelklicken Sie auf das Skript, um es im Skript-Editor zu öffnen.
Anatomie eines Modul-Skripts
Jeder ModuleScript startet mit dem folgenden Codes:
local module = {}return module
Dieser Code erstellt eine leere Luau-Tabelle und gibt sie an jedes Skript zurück, das das Skript, das. PL: die Skriptserfordert.
Der Rückgabewert kann jeder Datentyp sein, außer nil, aber die meisten Modul-Skripte geben eine Funktion, eine Tabelle oder eine Tabelle von Funktionen zurück. Um seinen Rückgabewert zu generieren, können Modul-Skripte natürlich beliebigen Codesausführen, der andere Modul-Skripte erfordert.
Das folgende Beispiel gibt eine Tabelle mit einer einzigen Funktion zurück, die getPickupBonus heißt. Fügen Sie sie in Ihr neues Skript, das. PL: die Skriptsein:
-- ModuleScript in ReplicatedStorage
local PickupManager = {}
local defaultMultiplier = 1.25
local rarityMultipliers = {
common = 10,
uncommon = 20,
rare = 50,
legendary = 100
}
-- Füge die getPickupBonus-Funktion der PickupManager-Tabelle hinzu
PickupManager.getPickupBonus = function(rarity)
local bonus = rarityMultipliers[rarity] * defaultMultiplier
return bonus
end
return PickupManager
Das Hinzufügen der Funktion zu einer Tabelle ist nicht streng nötig — Sie könnten einfach die Funktion selbst zurückgeben — aber es ist ein gutes Muster, das zu folgen, und es gibt Ihnen eine einfachen zu verstehende Syntax, wenn Sie die Funktion aus einem anderen Skript aufrufen und Sie einfach mehr Funktionen zum Modul-Skript hinzufügen können im Laufe der Zeit.
Benötigt Modul-Skripte
Um ein Skript, das. PL: die Skriptszu laden, rufen Sie die Funktion require() auf. In ReplicatedStorage fügen Sie ein neues Skript, das. PL: die Skriptshinzu und ändern Sie seine RunContext in 1>Client1>. Dann fügen Sie den folgenden Code hinzu, um die Funktion 4>PickupManager.getPickupBonus
Client-Skript in ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Werte von ModulScript erhaltenlocal PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))-- Rufen Sie eine ModuleScript-Funktion auflocal bonus = PickupManager.getPickupBonus("legendary")print(bonus) --> 125
Du kannst den gleichen Code verwenden, um das Skript von ServerScriptService zu benötigen:
Script in ServerScriptStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Holen Sie sich den Rückgabewert für das ModulScript namens "PickupManager"local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))
Wenn Sie require() auf einem ModuleScript aufrufen, wird es einmal ausgeführt und gibt einen einzelnen Gegenstand als Referenz zurück. Wenn Sie require()
Wenn Sie ein ModuleScript von beiden Seiten der Client-Server-Grenze benötigen, gibt das ModuleScript eine eindeutige Referenz für jede Seite zurück.
Muster
Modul-Skripte haben einige gemeinsame Muster, die Sie verwenden können, um Ihren Code zu vereinfachen und Fallstricke zu vermeiden, wenn Ihr Erlebnis an Größe und Komplexität gewinnt.
Daten teilen
Um Daten mit einzelnen Objekten zu verknüpfen, kannst du ihnen Attribute zuweisen oder Configuration Ordner mit Wertobjekten wie StringValue oder IntValue erstellen. jedoch, beide Ansätze sind problematisch, wenn du Dutzende von Objekten oder Datenwerten hinzufügen oder modifizieren möchtest. Sie speichern auch keine Tabellen oder Funktionen.
Wenn Sie dieselben Daten für mehrere Kopien desselben Objekts modifizieren oder dieselben Daten für verschiedene Objekte wiederverwenden möchten, speichern Sie die Daten in ModuleScripts . Es ist ein einfacher Weg für Sie, die Daten in anderen Skripts wiederzuverwenden, und Sie können Tabellen und Funktionen speichern.
Das folgende Beispiel ModuleScript in ReplicatedStorage speichert die Konfigurationswerte für eine generische Waffe:
ModuleScript in ReplicatedStorage
local GunConfig = {}GunConfig.MagazineSize = 20GunConfig.AmmoCount = 100GunConfig.Firerate = 600GunConfig.Damage = {["Head"] = 50;["Torso"] = 40;["Body"] = 25;}return GunConfig
Benutzerdefinierte Ereignisse
Benutzerdefinierte Ereignisse ermöglichen es Skripten, miteinander zu kommunizieren, aber die Nachverfolgung von Verweisen auf einzelne Class.BindableEvent -Objekte kann Ihren Codesüberladen.
Sie können ModuleScripts verwenden, um BindableEvents zu speichern und benutzerdefinierte Ereignishändler bereitzustellen, die direkt an die Methoden von ModuleScript gebunden sind.
Das folgende ModuleScript in ReplicatedStorage hat ein benutzerdefiniertes Ereignis, das ausgeführt wird, wenn der Schalter Zustand ändert:
ModuleScript in ReplicatedStorage
local Switch = {}
-- Erstellen von Bindungen, damit jedes Skript zuhören kann, wenn der Schalter geändert wird
local bindableEvent = Instance.new("BindableEvent")
Switch.Changed = bindableEvent.Event
local state = false
function Switch.flip()
state = not state
bindableEvent:Fire(state)
end
return Switch
Das folgende Client-Skript in ReplicatedStorage verbindet eine Funktion, die aufgerufen wird, wenn das Ereignis Switch.Changed ausgelöst wird.
Script in ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Switch = require(ReplicatedStorage:WaitForChild("Switch"))
Switch.Changed:Connect(function(newState)
print("Switch state is now", newState)
end
-- Testen Sie das Flippen ein paar Mal
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()
Kapselung
Kapselung ist die Praxis, eine Abstraktionsschicht um Objekte oder Skriptlogik zu erstellen, um die Komplexität zu verbergen. Sie können ModuleScripts verwenden, um Roblox-Objekte mit benutzerdefinierten Lua-Funktionen zu kapseln, um den Codeszu vereinfachen.
Zum Beispiel können Sie Kapselung verwenden, um:
- Vereinfachen Sie die netzwerkübergreifende Kommunikation mit einem einzigen RemoteEvent Objekt.
- Wrap error handling code um sensible Dienste wie DataStoreService.
- Definieren Sie benutzerdefinierte Methoden, um Roblox-Objektfunktionen zu steuern oder zu erweitern.
Es ist schwierig, Dutzende einzelner RemoteEvent -Objekte zu verfolgen, um Netzwerke in deinem Spiel zu implementieren. Du kannst ein ModuleScript verwenden, um ein einzelnes RemoteEvent zu kapseln, um dieses Problem zu vereinfachen. Indem du ein einzigart
Im folgenden Beispiel kapselt das ModuleScript mit dem Namen NetworkManagerClient die ArgumentClass.Remote
Das folgende ModuleScript in ReplicatedFirst bietet eine gekapselte Funktion, die Sie auf Ihre Client-Skripte aufrufen können, um eine Netzwerk-Nachricht zu senden:
Netzwerk-Modul
-- ModuleScript in ReplicatedFirst mit dem Namen NetworkManagerClient
local NetworkManagerClient = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
-- Einschließen der Remote-Objekt-FireServer-Funktion
function NetworkManagerClient.FireServer(id, ...)
remoteEvent:FireServer(id, ...)
end
return NetworkManagerClient
Das folgende ModuleScript in ServerScriptService verwendet BindableEvents für jedes Skript, um sich mit einer bestimmten ID zu verbinden. Wenn ein Client eine Netzwerk-Nachricht sendet, wird jeder 1> Class.BindableEvent1> , der mit der angegebenen ID verbunden ist, ausgelöst.
-- ModuleScript im ServerScriptService namens NetworkManagerServer
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- Verknüpfung des neuen Bindbaren Ereignisses mit der ID
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- Verbindung mit
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- Alle verbindbaren Ereignisse finden, die der ID des erhaltenen Remote-Events entsprechen
for _, signal in networkSignalList do
if signal.id == id then
signal.bindableEvent:Fire(player, ...)
end
end
end)
return NetworkManagerServer
Der folgende LocalScript sendet eine Nachricht mit der ID RequestA mit einem optionalen Hello-Argument.
-- Lokales Skript in ReplicatedFirstlocal ReplicatedFirst = game:GetService("ReplicatedFirst")local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))NetworkManagerClient.FireServer("RequestA", "Hello")
Das folgende Script verbindet sich mit der Netzwerk-Nachricht-ID RequestA und druckt eine Anweisung mit allen zusätzlichen Parametern aus, wenn es die Anfrage erhält.
-- Script in ServerScriptService
local ServerScriptService = game:GetService("ServerScriptService")
local NetworkManagerServer = require(ServerScriptService:WaitForChild("NetworkManagerServer"))
NetworkManagerServer.GetServerEventSignal("RequestA"):Connect(function(player, ...)
print("Received RequestA from", player, ...)
end)