Birkaç script oluşturduktan sonra, aralarında bazı kodları yeniden kullanmak istemek uzun sürmez. Konuma bağlı olarak, ModuleScripts, kodları istemci-sunucu sınırının farklı tarafları veya sınırın aynı tarafında bulunan scriptler arasında yeniden kullanmanıza olanak tanır.
Modül scriptlerini, scriptleri koyduğunuz her yere koyabilirsiniz, ancak ReplicatedStorage popüler bir yerdir; modül scriptlerini burada saklamak, kodu sunucu ve istemciler arasında yeniden kullanmanıza olanak tanır.
Modül scriptinin anatomisi
Roblox Studio'da, ReplicatedStorage'a bir modül scripti ekleyin ve adını PickupManager olarak değiştirin. Her ModuleScript, aşağıdaki kodla başlar:
local module = {}return module
Bu kod, boş bir Luau tablo oluşturur ve bunu modül scriptini gerektiren her script'e döndürür.
Dönüş değeri nil haricindeki herhangi bir veri tipi olabilir, ancak çoğu modül scripti bir fonksiyon, bir tablo veya fonksiyonların bir tablosunu döndürür. Modül scriptleri, dönüş değerini oluşturmak için elbette diğer modül scriptlerini gerektirmek de dahil olmak üzere keyfi kodu çalıştırabilir.
Aşağıdaki örnek, getPickupBonus adında tek bir fonksiyonla bir tablo döndürür. Bunu yeni modül scriptinize yapıştırın:
-- ReplicatedStorage'taki ModülScript
local PickupManager = {}
local defaultMultiplier = 1.25
local rarityMultipliers = {
common = 10,
uncommon = 20,
rare = 50,
legendary = 100
}
-- PickupManager tablosuna getPickupBonus fonksiyonunu ekleyin
PickupManager.getPickupBonus = function(rarity)
local bonus = rarityMultipliers[rarity] * defaultMultiplier
return bonus
end
return PickupManager
Bir fonksiyonu bir tabloya eklemek kesinlikle gerekli değildir; fonksiyonu doğrudan döndürebilirsiniz, ancak bu takip etmesi kolay bir sözdizimi sağlar; bu, başka bir script'ten fonksiyonu çağırdığınızda anlamanızı kolaylaştırır ve zamanla modül scriptine daha fazla fonksiyon eklemenizi sağlar.
Modül scriptlerini gerektirme
Bir modül scriptini yüklemek için require() fonksiyonunu çağırırsınız. ReplicatedStorage'da yeni bir script ekleyin ve RunContext'ini Client olarak değiştirin. Ardından, PickupManager.getPickupBonus fonksiyonunu çağırmak için aşağıdaki kodu ekleyin:
ReplicatedStorage'taki İstemci scriptilocal ReplicatedStorage = game:GetService("ReplicatedStorage")-- ModülScript tarafından döndürülen değeri alınlocal PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))-- Bir ModülScript fonksiyonunu çağırınlocal bonus = PickupManager.getPickupBonus("legendary")print(bonus) --> 125
Modül scriptlerini ReplicatedStorage'da saklamak, kodunuzu sunucu ve istemci arasında paylaşmanıza olanak tanır, böylece scripti ServerScriptService'den gerektirmek için aynı kodu kullanabilirsiniz:
ServerScriptService'taki Scriptlocal ReplicatedStorage = game:GetService("ReplicatedStorage")local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))
require() fonksiyonunu bir ModuleScript üzerinde çağırdığınızda, bu yalnızca bir kez çalışır ve bir referans olarak tek bir nesne döndürür. require() fonksiyonunu tekrar çağırmak, tam olarak aynı referansı döndürür; bu, döndürülen tablo veya Instance'ı değiştirdiğinizde, sonraki require() çağrılarının o değiştirilmiş referansı döndürmesi anlamına gelir. Modül kendisi birden fazla kez çalışmaz.
Bir ModuleScript'i istemci-sunucu sınırının her iki tarafında gerektirirseniz, yukarıdaki örnekte olduğu gibi, ModuleScript, her taraf için benzersiz bir referans döndürür.
Kalıplar
Modül scriptlerinin, oyununuz büyüdükçe kodunuzu basitleştirmek ve tuzaklardan kaçınmak için kullanabileceğiniz bazı yaygın kalıpları vardır.
Veri paylaşımı
Bireysel nesnelerle veriyi ilişkilendirmek için, onlara özellikler atayabilir veya Configuration klasörleri oluşturabilirsiniz; bunlar, StringValue veya IntValue gibi değer nesneleri içerir. Ancak, bu iki yaklaşım, onlarca nesne veya veri değeri eklemek veya değiştirmek istiyorsanız sorun yaratır. Ayrıca tabloları veya fonksiyonları saklamazlar.
Aynı veriyi birden fazla kopyası için değiştirmek veya farklı nesneler için aynı veriyi yeniden kullanmak istiyorsanız, verileri ModuleScripts içinde saklayın. Bu, diğer scriptlerde veriyi yeniden kullanmanın daha kolay bir yoludur ve tabloları ve fonksiyonları saklayabilirsiniz.
Aşağıdaki örnek ModuleScript, ReplicatedStorage'da, genel bir silah için yapılandırma değerlerini saklar:
ReplicatedStorage'taki ModülScriptlocal GunConfig = {}GunConfig.MagazineSize = 20GunConfig.AmmoCount = 100GunConfig.Firerate = 600GunConfig.Damage = {["Head"] = 50;["Torso"] = 40;["Body"] = 25;}return GunConfig
Özel olaylar
Özel olaylar, scriptlerin birbirleriyle iletişim kurmasını sağlar, ancak her bir BindableEvent nesnesine referansları takip etmek, kodunuzu dağınık hale getirebilir.
ModuleScripts'leri, BindableEvents'leri saklamak ve ModuleScript metodlarına doğrudan bağlı özel olay işleyicileri sağlamak için kullanabilirsiniz.
Aşağıdaki ModuleScript, ReplicatedStorage'da, anahtarın durumu değiştiğinde tetiklenen bir özel olaya sahiptir:
ReplicatedStorage'taki ModülScript
local Switch = {}
-- Anahtar değiştiğinde herhangi bir script’in dinleyebilmesi için oluşturulmuş bindable
local bindableEvent = Instance.new("BindableEvent")
Switch.Changed = bindableEvent.Event
local state = false
function Switch.flip()
state = not state
bindableEvent:Fire(state)
end
return Switch
Aşağıdaki istemci scripti ReplicatedStorage'da, Switch.Changed olayı tetiklendiğinde çağrılacak bir fonksiyona bağlanır.
ReplicatedStorage'taki Script
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Switch = require(ReplicatedStorage:WaitForChild("Switch"))
Switch.Changed:Connect(function(newState)
print("Anahtar durumu artık", newState)
end)
-- Anahtarı birkaç kez çevirme testi
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()
Kapsülleme
Kapsülleme, nesneler veya script mantığı etrafında bir soyutlama katmanı oluşturarak karmaşıklığı gizleme uygulamasıdır. Kodunuzu basitleştirmek için ModuleScripts'i Roblox nesnelerini özel Luau fonksiyonları ile kapsüllemek için kullanabilirsiniz.
Örneğin, kapsüllemeyi kullanarak:
- Tek bir RemoteEvent nesnesi ile ağ iletişimini basitleştirin.
- DataStoreService gibi hassas hizmetlerin etrafında hata işleme kodu sarın.
- Roblox nesne özelliklerini kontrol etmek veya genişletmek için özel yöntemler tanımlayın.
Oyun içinde ağ iletişimini uygulamak için onlarca bireysel RemoteEvent nesnesini takip etmek zordur. Bu sorunu basitleştirmek için tek bir ModuleScript kullanarak bir RemoteEvent'i kapsüllemeniz mümkündür. Eşsiz bir id argümanı ekleyerek, yalnızca tek bir RemoteEvent kullanarak farklı ağ mesajları göndermeye devam edebilirsiniz.
Aşağıdaki örnekte, NetworkManagerClient adlı ModuleScript, RemoteEvent:FireServer() metodunu bu ekstra id argümanını kapsüllemek için kapsüller. Ayrıca, bu ModuleScript, diğer kod parçalarınızda referans almanıza gerek kalmadan RemoteEvent nesnesini de referans alır. Ağ mesajları göndermek için yalnızca bu ModuleScript'i gerektirmeniz yeterlidir ve diğer kod tabanınızda RemoteEvent nesneleri ile uğraşmanıza gerek kalmaz.
Aşağıdaki ModuleScript, ReplicatedFirst içinde, istemci scriptlerinizle bir ağ mesajı göndermek için çağırabileceğiniz bir kapsüllenmiş fonksiyon sunar:
Ağ Modülü
-- ReplicatedFirst içinde NetworkManagerClient adlı ModülScript
local NetworkManagerClient = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
-- Uzak nesnenin FireServer fonksiyonunu kapsüllüyor
function NetworkManagerClient.FireServer(id, ...)
remoteEvent:FireServer(id, ...)
end
return NetworkManagerClient
Aşağıdaki ModuleScript, ServerScriptService içinde, her bir script'in belirli bir ID'ye bağlanması için BindableEvents kullanır. Bir istemci bir ağ mesajı gönderdiğinde, belirtilen ID ile ilişkilendirilmiş her BindableEvent tetiklenir.
-- ServerScriptService içindeki NetworkManagerServer adlı ModülScript
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- Yeni BindableEvent'i ID'ye bağlıyoruz
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- Bağlantı sağlama
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- Alınan uzak olayın ID'siyle eşleşen her bir bağlı olayı bulma
for _, signal in networkSignalList do
if signal.id == id then
signal.bindableEvent:Fire(player, ...)
end
end
end)
return NetworkManagerServer
Aşağıdaki LocalScript, RequestA ID'si ile birlikte isteğe bağlı bir Hello argümanı ile bir mesaj gönderir.
-- ReplicatedFirst içinde LocalScriptlocal ReplicatedFirst = game:GetService("ReplicatedFirst")local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))NetworkManagerClient.FireServer("RequestA", "Hello")
Aşağıdaki Script, ağ mesajı ID'si RequestA ile bağlanır ve isteği aldığında herhangi bir ek parametre ile bir ifadenin basılmasını sağlar.
-- ServerScriptService içindeki Script
local ServerScriptService = game:GetService("ServerScriptService")
local NetworkManagerServer = require(ServerScriptService:WaitForChild("NetworkManagerServer"))
NetworkManagerServer.GetServerEventSignal("RequestA"):Connect(function(player, ...)
print("Received RequestA from", player, ...)
end)