ใช้รหัสซ้ำ

*เนื้อหานี้แปลโดยใช้ AI (เวอร์ชัน Beta) และอาจมีข้อผิดพลาด หากต้องการดูหน้านี้เป็นภาษาอังกฤษ ให้คลิกที่นี่

หลังจากสร้างสคริปต์ไม่กี่อันแล้ว มันไม่เคยนานก่อนที่คุณจะต้องการใช้ซ้ำโค้ดระหว่างพวกเขาขึ้นอยู่กับ ตำแหน่งModuleScripts ทำให้คุณสามารถใช้ซ้ำโค้ดระหว่างสคริปต์บนด้านต่างๆ ของขอบเขตไคลเอนต์-เซิร์ฟเวอร์หรือด้านเดียวกันของขอบเขต

คุณสามารถวางสคริปต์โมดูลได้ทุกที่ที่คุณวางสคริปต์ แต่ ReplicatedStorage เป็นตำแหน่งยอดนิยม; การเก็บสคริปต์โมดูลไว้ที่นี่ช่วยให้คุณสามารถใช้ซ้ำรหัสระหว่างเซิร์ฟเวอร์และไคลเอนต์ได้

โครงสร้างของสคริปต์โมดูล

ใน Roblox Studio เพิ่มสคริปต์โมดูลไปที่ ReplicatedStorage และเปลี่ยนชื่อเป็น PickupManager แต่ละ ModuleScript รหัส:


local module = {}
return module

รหัสนี้สร้างโต๊ะ Luau ว่างเปล่า และส่งคืนให้กับสคริปต์ใดก็ได้ที่ต้องการสคริปต์โมดูล

ค่าการ返回สามารถเป็นประเภทข้อมูลใดก็ได้ ยกเว้น แต่ส่วนใหญ่ของสคริปต์โมดูลจะคืนฟังก์ชัน ตาราง หรือตารางของฟังก์ชันเพื่อสร้างมูลค่าการคืนของมันโค้ดสคริปต์ของโมดูลสามารถเรียกใช้รหัสอย่างอิสระซึ่งรวมถึงการต้องใช้โค้ดสคริปต์โมดูลอื่น

ตัวอย่างต่อไปนี้จะคืนตารางที่มีฟังก์ชันเดียวชื่อว่า getPickupBonus ใส่ลงในสคริปต์โมดูลใหม่:


-- ModuleScript ใน ReplicatedStorage
local PickupManager = {}
local defaultMultiplier = 1.25
local rarityMultipliers = {
common = 10,
uncommon = 20,
rare = 50,
legendary = 100
}
-- เพิ่มฟังก์ชัน getPickupBonus ในตาราง PickupManager
PickupManager.getPickupBonus = function(rarity)
local bonus = rarityMultipliers[rarity] * defaultMultiplier
return bonus
end
return PickupManager

ติดตาม; มันให้คุณสามารถเพิ่มฟังก์ชันเพิ่มเติมในสคริปต์อื่นได้ง่ายเมื่อเรียกฟังก์ชันจากสคริปต์อื่นและทำให้คุณสามารถเพิ่มฟังก์ชันเพิ่มเติมในสคริปต์ของโมดูลได้อย่างง่ายดายในเวลาต่อมา

ต้องการสคริปต์โมดูล

เพื่อโหลดสคริปต์โมดูลคุณเรียกฟังก์ชัน require()ใน ReplicatedStorage , เพิ่มสคริปต์ใหม่, และเปลี่ยน RunContext เป็น Clientจากนั้นเพิ่มโค้ดต่อไปนี้เพื่อเรียกฟังก์ชัน PickupManager.getPickupBonus :

สคริปต์ไคลเอนต์ใน ReplicatedStorage

local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- รับค่าที่ส่งคืนโดย ModuleScript
local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))
-- เรียกฟังก์ชัน ModuleScript
local bonus = PickupManager.getPickupBonus("legendary")
print(bonus) --> 125

การเก็บสคริปต์โมดูลใน ReplicatedStorage ช่วยให้คุณสามารถแบ่งปันโค้ดระหว่างเซิร์ฟเวอร์และไคลเอนต์ได้ ดังนั้นคุณสามารถใช้โค้ดเดียวกันเพื่อต้องการสคริปต์จาก ServerScriptService :

สคริปต์ใน ServerScriptService

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PickupManager = require(ReplicatedStorage:WaitForChild("PickupManager"))

เมื่อคุณเรียก require() บน ModuleScript มันจะทำงานครั้งเดียวและส่งคืนไอเทมเดียวเป็นข้อมูลอ้างอิงการเรียก อีกครั้งจะส่งคืนคำอ้างอิงเดียวกันอีกครั้ง ซึ่งหมายความว่าหากคุณแก้ไข ตาราง หรือ ต่อไปการโทรกลับจะส่งคืนคำอ้างอิงที่แก้ไขนั้นโมดูลเองไม่ได้ทำงานหลายครั้ง

หากต้องการ ModuleScript จากทั้งสองด้านของขอบเขตไคลเอนต์-เซิร์ฟเวอร์ เช่นในตัวอย่างด้านบน ค่า ModuleScript จะส่งคืนการอ้างอิงที่ไม่ซ้ำกันสำหรับแต่ละด้าน

รูปแบบ

สคริปต์โมดูลมีลายทั่วไปที่คุณสามารถใช้เพื่อลดความซับซ้อนของโค้ดและหลีกเลี่ยงจุดบกพร่องตามที่ประสบการณ์ของคุณเติบโตไปในขนาดและความซับซ้อน

การแบ่งปันข้อมูล

เพื่อเชื่อมโยงข้อมูลกับวัตถุแต่ละอย่าง คุณสามารถกำหนดค่าตัวละครให้กับพวกเขาหรือสร้างโฟลเดอร์ Configuration ที่มีวัตถุมูลค่าเช่น StringValue หรือ IntValueอย่างไรก็ตาม ทั้งสองวิธีนี้มีปัญหาหากคุณต้องการเพิ่มหรือแก้ไขโอบเจตหรือค่าข้อมูลหลายสิบรายการพวกเขายังไม่เก็บตารางหรือฟังก์ชัน

หากต้องการแก้ไขข้อมูลเดียวกันสําหรับหลายสำเนาของวัตถุเดียวกันหรือใช้ข้อมูลเดียวกันสําหรับวัตถุที่แตกต่างกัน ให้จัดเก็บข้อมูลใน ModuleScriptsเป็นวิธีที่ง่ายกว่าสำหรับคุณในการนำข้อมูลกลับมาใช้ในสคริปต์อื่น และคุณสามารถเก็บตารางและฟังก์ชันได้

ตัวอย่างต่อไปนี้ ModuleScript ใน ReplicatedStorage เก็บค่าการกำหนดค่าสําหรับปืนทั่วไป:

ModuleScript ใน ReplicatedStorage

local GunConfig = {}
GunConfig.MagazineSize = 20
GunConfig.AmmoCount = 100
GunConfig.Firerate = 600
GunConfig.Damage = {
["Head"] = 50;
["Torso"] = 40;
["Body"] = 25;
}
return GunConfig

อีเวนต์ที่กําหนดเอง

กิจกรรมที่กําหนดเองช่วยให้สคริปต์สื่อสารกับกันและกัน แต่ต้องติดตามการอ้างอิงถึงวัตถุแต่ละ BindableEvent อาจทําให้โค้ดของคุณรกรุง

คุณสามารถใช้ ModuleScripts เพื่อเก็บ BindableEvents และให้ตัวจัดการอีเวนต์ที่กําหนดเองที่เชื่อมโยงโดยตรงกับวิธีการของ ModuleScript

ต่อไปนี้ ModuleScript ใน ReplicatedStorage มีอีเวนต์ที่กําหนดเองที่จะเปิดเมื่อสวิตช์เปลี่ยนสถานะ:

ModuleScript ใน ReplicatedStorage

local Switch = {}
-- สร้างบายนาเบิลเพื่อให้สคริปต์ใดๆ สามารถฟังได้เมื่อสวิตช์ถูกเปลี่ยน
local bindableEvent = Instance.new("BindableEvent")
Switch.Changed = bindableEvent.Event
local state = false
function Switch.flip()
state = not state
bindableEvent:Fire(state)
end
return Switch

สคริปต์ไคลเอนต์ต่อไปนี้ใน ReplicatedStorage เชื่อมต่อฟังก์ชันเพื่อโทรเมื่อเหตุการณ์ Switch.Changed เกิดขึ้น

สคริปต์ใน ReplicatedStorage

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Switch = require(ReplicatedStorage:WaitForChild("Switch"))
Switch.Changed:Connect(function(newState)
print("Switch state is now", newState)
end
-- ทดสอบการพลิกไม่กี่ครั้ง
task.wait(1)
Switch.flip()
task.wait(1)
Switch.flip()

การแคปซูล

การแคปซูลคือการปฏิบัติในการสร้างชั้นของการสังเกตรอบวัตถุหรือโลจิสติกการเขียนโค้ดเพื่อซ่อนความซับซ้อนคุณสามารถใช้ ModuleScripts เพื่อแคปซูลวัตถุ Roblox ด้วยฟังก์ชัน Luau ที่กําหนดเองเพื่อลดความซับซ้อนของโค้ด

ตัวอย่างเช่นคุณสามารถใช้การแคปซูลเพื่อ:

  • เรียบง่ายการสื่อสารระหว่างเครือข่ายด้วยวัตถุเดียว RemoteEvent
  • ห่อรหัสการจัดการข้อผิดพลาดรอบบริการที่บอบบางเช่น DataStoreService
  • กำหนดวิธีการที่กำหนดเองเพื่อควบคุมหรือขยายคุณลักษณะของวัตถุ Roblox

ยากที่จะติดตามวัตถุหลายสิบชิ้น RemoteEvent เพื่อใช้งานเครือข่ายในเกมของคุณคุณสามารถใช้ ModuleScript เพื่อแคปซูลเดียว RemoteEvent เพื่อช่วยลดปัญหานี้โดยการรวมอาร์กิวเมนต์ที่ไม่ซ้ำกัน id คุณยังคงสามารถส่งข้อความเครือข่ายที่แตกต่างกันได้โดยใช้เพียงอันเดียว RemoteEvent

ในตัวอย่างด้านล่าง ModuleScript ชื่อ NetworkManagerClient บรรจุวิธี RemoteEvent:FireServer() เพื่อรวมอาร์กิวเมนต์เพิ่มเติม idนอกจากนี้ยังมีการอ้างอิง ModuleScript ไปยังวัตถุเอง RemoteEvent ดังนั้นคุณจึงไม่จำเป็นต้องอ้างถึงในส่วนอื่นๆ ของโค้ดคุณต้องการเพียงส่งข้อความเครือข่ายนี้ ModuleScript เท่านั้นและไม่จำเป็นต้องจัดการกับวัตถุ RemoteEvent ในส่วนที่เหลือของคอดีบาสของคุณ

ต่อไปนี้ ModuleScript ใน ReplicatedFirst ให้ฟังก์ชันแคปซูลที่คุณสามารถเรียกใช้บนสคริปต์ไคลเอนต์เพื่อส่งข้อความเครือข่าย:

โมดูลเครือข่าย

-- ModuleScript ใน ReplicatedFirst ชื่อว่า NetworkManagerClient
local NetworkManagerClient = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
-- บรรจุฟังก์ชัน FireServer ของวัตถุระยะไกล
function NetworkManagerClient.FireServer(id, ...)
remoteEvent:FireServer(id, ...)
end
return NetworkManagerClient

ต่อไปนี้ ModuleScript ใน ServerScriptService ใช้ BindableEvents สำหรับทุกสคริปต์ที่จะเชื่อมต่อกับ ID เฉพาะเมื่อไคลเอนต์ส่งข้อความเครือข่ายแต่ละ BindableEvent ที่เกี่ยวข้องกับรหัสที่ระบุจะเกิดขึ้น


-- ModuleScript ใน ServerScriptService ชื่อ NetworkManagerServer
local NetworkManagerServer = {}
local networkSignalList = {}
function NetworkManagerServer.GetServerEventSignal(id)
local bindableEvent = Instance.new("BindableEvent")
-- เชื่อมโยง BindableEvent ใหม่กับ id
table.insert(networkSignalList, {
id = id,
bindableEvent = bindableEvent,
})
return bindableEvent.Event
end
-- เชื่อมต่อกับ
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")
remoteEvent.OnServerEvent:Connect(function(player, id, ...)
-- ค้นหาทุกอีเวนต์ที่สามารถผูกได้ที่ตรงกับรหัสอีเวนต์ระยะไกลที่ได้รับ
for _, signal in networkSignalList do
if signal.id == id then
signal.bindableEvent:Fire(player, ...)
end
end
end)
return NetworkManagerServer

ต่อไปนี้ LocalScript ส่งข้อความด้วยรหัส RequestA พร้อมอาร์กิวเมนต์ทางเลือก Hello


-- สคริปต์ท้องถิ่นใน ReplicatedFirst
local ReplicatedFirst = game:GetService("ReplicatedFirst")
local NetworkManagerClient = require(ReplicatedFirst:WaitForChild("NetworkManagerClient"))
NetworkManagerClient.FireServer("RequestA", "Hello")

ต่อไปนี้ Script เชื่อมต่อกับ ID ข้อความเครือข่าย RequestA และพิมพ์คำสั่งใดๆ ที่มีพารามิเตอร์เพิ่มเติมเมื่อได้รับคำขอ


-- สคริปต์ใน ServerScriptService
local ServerScriptService = game:GetService("ServerScriptService")
local NetworkManagerServer = require(ServerScriptService:WaitForChild("NetworkManagerServer"))
NetworkManagerServer.GetServerEventSignal("RequestA"):Connect(function(player, ...)
print("Received RequestA from", player, ...)
end)