Po utworzeniu kilku skryptów nigdy nie jest długo, zanim chcesz ponownie użyć niektórego kodu między nimi. W zależności od lokalizacji , ModuleScripts pozwala ci na ponowne używanie kodu między skryptami na różnych stronach granicy klienta-serwera lub tej samej strony granicy.
Tworzenie Skryptów Modułowych
Możesz umieścić modułowe skrypcje w dowolnym miejscu, w którym umieszczasz skrypcie, ale ReplicatedStorage jest popularnym lokalem; przechowywanie modułowych skryptów tutaj pozwala ci na ponowne używanie kodu między serwerem a klientami.
- W Roblox Studio, PrzenieśStorage w oknie Eksplorator i kliknij +.
- Wybierz ModuleScript , aby dodać nowy skrypt modułu.
- Prawe kliknięcie skryptu i zmiana go na PickupManager .
- Podwójnie kliknij skrypt, aby otworzyć go w Skrypt Editor .
Anatomia modułowego skryptu
Każdy ModuleScript zaczyna się od następującego kodu:
local module = {}return module
Ten kod tworzy pustą tabelę Luau i zwraca go do dowolnego skryptu, który wymaga skryptu modułu.
Wartość zwrotu może być dowolnym typem danych poza nil, ale większość skryptów modułowych generuje wartość zwrotu, tabelę lub tabelę funkcji. Aby generować jego wartość, skrypty modułowe mogą oczywiście wykonawać dowolny kod, w tym wymagający innych modułów skryptów.
Poniższy przykład zwraca tabelę z jedną funkcją nazyającą się getPickupBonus . Wklej go do swojego nowego modułowego skryptu:
-- ModuleScript w ReplicatedStorage
local PickupManager = {}
local defaultMultiplier = 1.25
local rarityMultipliers = {
common = 10,
uncommon = 20,
rare = 50,
legendary = 100
}
-- Dodaj funkcję getPickupBonus do tabeli PickupManager
PickupManager.getPickupBonus = function(rarity)
local bonus = rarityMultipliers[rarity] * defaultMultiplier
return bonus
end
return PickupManager
Dodanie funkcji do tabeli nie jest wymagane ściśle — możesz po prostu zwrócić funkcję sam — ale to dobry wzór do naśladowania; daje ci łatwy do zrozumienia styl kiedy wzywasz funkcję z innego skryptu i umożliwia łatwo dodawanie więcej funkcji do modułowego skryptu w ciągu czasu.
Wymagające Skrypt Modułowych
Aby załadować modułowy skrypt, wezwiecie funkcję require(). W ReplicatedStorage dodaj nowy skrypt, a zmień jego RunContext na 2> Client2>. Następnie dodaj następujący kod, aby wejść w funkcję 5> PickupManager.getPickupBonus
Skrypt klienta w ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Zdobądź wartość zwróconą przezModuleScriptlocal PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))-- Wezwij funkcję ModuleScriptlocal bonus = PickupManager.getPickupBonus("legendary")print(bonus) --> 125
Możesz użyć tego samego kodu, aby wymagać skryptu z ServerScriptService :
Skrypt w ServerScriptStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")-- Zdobądź wartość zwrotu dla ModułScript nazywającego się "PickupManager"local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))
Kiedy wzyjesz require() na ModuleScript, to zostanie wykonane raz i zwróci jeden pojedynczy element jako odniesienie. Wezwanie Global.LuaGlobals.wymagać()</
Jeśli wymagasz ModuleScript z obu stron granicy klienta-serwera, ModuleScript zwraca unikalny identyfikator dla każdej strony.
Wzory
Skrypty modułu mają kilka zbliżonych wzorców, które możesz użyć do uproszczenia swojego kodu i uniknięcia pułapek, gdy twoje doświadczenie rośnie w rozmiarze i złożoności.
Udostępnianie danych
Aby powiązać dane z poszczególnymi obiektami, możesz im przypisać atrybuty lub stworzyć Configuration katalogi z obiektami wartości, takimi jak StringValue lub IntValue. Jnak, obie podejścia są problematyczne, jeśli chcesz dodać lub zmienić tuziny obiektów lub wartości danych. One również nie
Jeśli chcesz zmodyfikować te same dane dla kilku kopii tego samego obiektu lub ponownie użyć tych samych danych dla różnych obiektów, przechowuj dane w ModuleScripts . To łatwiejszy sposób na ponowne używanie danych w innych skryptach i możesz przechować tabeli i funkcje.
Poniższy przykład ModuleScript w ReplicatedStorage przechowuje wartości konfiguracji dla generycznej broni:
ModuleScript w ReplicatedStorage
local GunConfig = {}GunConfig.MagazineSize = 20GunConfig.AmmoCount = 100GunConfig.Firerate = 600GunConfig.Damage = {["Head"] = 50;["Torso"] = 40;["Body"] = 25;}return GunConfig
Wydarzenia niestandardowe
Wydarzenia niestandardowe umożliwiają skryptom komunikację ze sobą, ale konieczność śledzenia odniesień do poszczególnych obiektów BindableEvent może zbuntować twój kod.
Możesz użyć ModuleScripts to przechować BindableEvents i zapewnić niestandardowe wiązania wydarzeń, które są bezpośrednio powiązane z metodami ModuleScript .
Następujące ModuleScript w ReplicatedStorage ma wbudowany wążąd, który uruchamia się, gdy przełącznik zmienia stan:
ModuleScript w ReplicatedStorage
local Switch = {}
-- Tworzenie przycisku, aby każdy skrypt słuchał, gdy przełącznik został zmieniony
local bindableEvent = Instance.new("BindableEvent")
Switch.Changed = bindableEvent.Event
local state = false
function Switch.flip()
state = not state
bindableEvent:Fire(state)
end
return Switch
Poniższy kod klienta w ReplicatedStorage połącza funkcję do wywołania, gdy wydarzenie Switch.Changed zostanie uruchomione.
Skrypt w ReplicatedStorage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Switch = require(ReplicatedStorage:WaitForChild("Switch"))
Switch.Changed:Connect(function(newState)
print("Switch state is now", newState)
end
-- Zakręć kilka razy
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()
Zakapsułowanie
Zakapsułowanie to praktyka tworzenia warstwy abstrakcji wokół obiektów lub logiki skryptowej, aby ukryć złożoność. Możesz użyć ModuleScripts , aby zakapsułować obiekty Roblox z użyciem niestandardowych funkcji Lua, aby uproszczyć kod.
Na przykład możesz użyć kapsułowania, aby:
- Uproszcz komunikację sieciową za pomocą pojedynczego obiektu RemoteEvent.
- Owinądź kod handlowania błędem wokół wrażliwych usług, takich jak DataStoreService.
- Definiuj niestandardowe metody, aby kontrolować lub rozszerzać funkcje obiektu Roblox.
Trudno jest śledzić dziesiątki pojedynczych obiektów RemoteEvent do wdrożenia sieci w swojej gra. Możesz użyć ModuleScript , aby zakapsułować pojedynczy RemoteEvent , aby pomóc uproszczyć ten problem.
W poniższym przykładzie ModuleScript o nazwie NetworkManagerClient zakapsułuje metodę
Poniższy ModuleScript w ReplicatedFirst dostarcza zaimkapsulowaną funkcję, którą możesz wezwieć na swojej kodzie klienta, aby wysłać wiadomość sieciową:
Moduł sieciowy
-- ModuleScript w ReplicatedFirst nazywającym się NetworkManagerClient
local NetworkManagerClient = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
-- Zablokowanie funkcji FireServer zdalnego obiektu
function NetworkManagerClient.FireServer(id, ...)
remoteEvent:FireServer(id, ...)
end
return NetworkManagerClient
Poniższy ModuleScript w ServerScriptService używa BindableEvents dla każdego skryptu, aby połączyć się z okreśленnym ID. Gdy klient wysyła wiadomość sieciową, każdy 2>Class.BindableEvent2> powiązany z okreśленnym ID zostanie uruchomiony.
-- ModuleScript w ServerScriptService nazywającym się NetworkManagerServer
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- Połączenie nowego wiążącego wydarzenia z identyfikatorem
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- Łączenie z
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- Znalezienie wszystkich wiążących się wydarzeń, które odpowiadają otrzymanemu zdarzeniu zdalnemu
for _, signal in networkSignalList do
if signal.id == id then
signal.bindableEvent:Fire(player, ...)
end
end
end)
return NetworkManagerServer
Poniższy LocalScript wysyłuje wiadomość z ID RequestA z opcjonalnym argumentem Hello.
-- Lokalny Skrypt w ReplicatedFirstlocal ReplicatedFirst = game:GetService("ReplicatedFirst")local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))NetworkManagerClient.FireServer("RequestA", "Hello")
Poniższy Script połącza się z ID sieci RequestA i drukuje oświadczenie z dowolnymi parami dodatkowymi, gdy otrzymuje prośba.
-- Skrypt w ServerScriptService
local ServerScriptService = game:GetService("ServerScriptService")
local NetworkManagerServer = require(ServerScriptService:WaitForChild("NetworkManagerServer"))
NetworkManagerServer.GetServerEventSignal("RequestA"):Connect(function(player, ...)
print("Received RequestA from", player, ...)
end)