สำหรับนักพัฒนาหลายคน ความท้าทายพื้นฐานในการปรับตัวเข้ากับการเขียนสคริปต์ใน Roblox คือความสำคัญของตำแหน่งไฟล์และคุณสมบัติ Script.RunContext ขึ้นอยู่กับประเภทของสคริปต์ ตำแหน่งใน Explorer และบริบทการทำงาน สคริปต์สามารถทำงานได้แตกต่างกันมาก บางการเรียกใช้วิธีอาจล้มเหลว วัตถุในเกมของคุณอาจไม่สามารถเข้าถึงได้ หรือสคริปต์อาจไม่ทำงานเลย
สาเหตุของความซับซ้อนนี้คือเกม Roblox เป็นเกมหลายผู้เล่นโดยค่าเริ่มต้น สคริปต์ต้องมีความสามารถในการทำงานเฉพาะบนเซิร์ฟเวอร์ ทำงานเฉพาะบนไคลเอนต์ หรือแชร์กันระหว่างทั้งสองฝ่าย การพัฒนาของแพลตฟอร์ม Roblox ตลอดเวลายังทำให้สถานการณ์ซับซ้อนขึ้นอีก
ประเภทของสคริปต์
Roblox มีสคริปต์สามประเภท:
- Script - โค้ดที่ทำงานได้ทั้งบนเซิร์ฟเวอร์หรือไคลเอนต์ ขึ้นอยู่กับตำแหน่งและคุณสมบัติ Script.RunContext
- LocalScript - โค้ดที่ทำงานเฉพาะบนไคลเอนต์ ไม่มีบริบทการทำงาน
- ModuleScript - โค้ดที่คุณสามารถนำกลับมาใช้ใหม่ในสคริปต์อื่น ไม่มีบริบทการทำงาน
เมื่อคุณสร้าง Script บริบทการทำงานเริ่มต้นของมันคือ Legacy ซึ่งหมายความว่า a) เป็นสคริปต์ด้านเซิร์ฟเวอร์ และ b) จะทำงานเฉพาะเมื่ออยู่ในคอนเทนเนอร์เซิร์ฟเวอร์ เช่น ServerScriptService หรือ Workspace
- หากคุณเปลี่ยนบริบทการทำงานของสคริปต์เป็น Server มันก็สามารถทำงานใน ReplicatedStorage ได้เช่นกัน แต่เราไม่แนะนำให้ทำเช่นนั้น เนื้อหาของตำแหน่งนั้นจะถูกทำซ้ำไปยังไคลเอนต์ ดังนั้นจึงไม่ใช่ตำแหน่งที่ดีสำหรับสคริปต์ด้านเซิร์ฟเวอร์
- หากคุณเปลี่ยนบริบทการทำงานของสคริปต์เป็น Client มันสามารถทำงานใน ReplicatedStorage ได้เช่นกัน นอกจากนี้ยังสามารถทำงานใน StarterCharacterScripts และ StarterPlayerScripts คอนเทนเนอร์เริ่มต้นจะถูกคัดลอกไปยังไคลเอนต์ ดังนั้นสคริปต์ต้นฉบับ และ สคริปต์ที่คัดลอกจะทำงาน ซึ่งไม่เป็นที่ต้องการ
ในการเปลี่ยนบริบทการทำงานของสคริปต์ ให้เลือกมันใน Explorer และเปลี่ยนค่าในหน้าต่าง Properties

คำแนะนำ
ใส่ Script เดียวที่มี RunContext เป็น Client ลงใน ReplicatedStorage
ใส่ Script เดียวที่มี RunContext เป็น Server ลงใน ServerScriptService
ใช้ ModuleScripts สำหรับโค้ดของไคลเอนต์และเซิร์ฟเวอร์ให้มากที่สุดเท่าที่จะทำได้ ต้องการโมดูลเหล่านี้จากสคริปต์ไคลเอนต์และสคริปต์เซิร์ฟเวอร์ของคุณ
วิธีนี้จะทำให้โค้ดของคุณมีจุดเริ่มต้นเดียวทั้งในด้านไคลเอนต์และเซิร์ฟเวอร์ ซึ่งช่วยให้การจัดระเบียบง่ายขึ้นและทำให้แยกหรือปิดโมดูลที่มีปัญหาได้ง่าย เพิ่มฟังก์ชัน start() ในแต่ละ ModuleScript เพื่อให้โมดูลทั้งหมดสามารถโหลดก่อนที่คุณจะเริ่มดำเนินการโค้ดของพวกเขา:
Sample server script--!strictlocal ServerScriptService = game:GetService("ServerScriptService")local SampleModule = require(ServerScriptService.SampleModule)local AnotherSampleModule = require(ServerScriptService.AnotherSampleModule)SampleModule.start()AnotherSampleModule.start()Sample module--!strictlocal CollectionService = game:GetService("CollectionService")local NPC_TAG = "npc"local SampleModule = {}local function setUpNpc(npc: Instance)-- initialize each NPCendlocal function cleanUpNpc(npc: Instance)-- run when event firesendfunction SampleModule.start() -- add the function to the table-- example loop for setup based on tagsfor _, npc in CollectionService:GetTagged(NPC_TAG) dosetUpNpc(npc)end-- run functions when events fireCollectionService:GetInstanceAddedSignal(NPC_TAG):Connect(setUpNpc)CollectionService:GetInstanceRemovedSignal(NPC_TAG):Connect(cleanUpNpc)endreturn SampleModuleเพื่อแชร์โค้ด ใช้ ModuleScripts ใน ReplicatedStorage และเรียกใช้ในทั้งสคริปต์ไคลเอนต์และสคริปต์เซิร์ฟเวอร์ของคุณ
หากจำเป็นสำหรับเกมของคุณ ให้ทำซ้ำรูปแบบเดียวกันใน ReplicatedFirst โดยมีสคริปต์ไคลเอนต์เดียวและจำนวน ModuleScripts ที่น้อยที่สุดเพื่อใช้ในการแสดงหน้าจอโหลด สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ ReplicatedFirst ดูที่ Replication order
ใช้ LocalScripts อย่างประหยัด หากคุณต้องใช้ ให้ใส่ใน StarterCharacterScripts, StarterPlayerScripts, StarterGui หรือ StarterPack
สคริปต์ในคอนเทนเนอร์เหล่านี้จะถูกคัดลอกไปยังคอนเทนเนอร์ของผู้เล่นแทนที่จะทำงานจากตำแหน่งเดียว ซึ่งอาจทำให้การดีบักซับซ้อน การใช้ ReplicatedStorage สำหรับโค้ดของไคลเอนต์ช่วยให้คุณคลิกบรรทัดในหน้าต่าง Output และไปที่ ReplicatedStorage.YourScript (ตำแหน่งที่เสถียรของสคริปต์) แทนที่จะเป็น Players.YourName.PlayerScripts.YourLocalScript (ตำแหน่งชั่วคราวที่สคริปต์ถูกคัดลอกไปในระหว่างการทำงาน)
หลีกเลี่ยงการแนบสคริปต์โดยตรงกับอินสแตนซ์ใน Workspace แทนที่จะ แท็กอินสแตนซ์ และใช้ CollectionService เพื่อทำงานกับพวกเขาจาก ModuleScript เดียว
ข้อยกเว้นที่สำคัญคือหากคุณแจกจ่ายโมเดลหรือแพ็คเกจใน Creator Store ในกรณีนั้น คุณอาจต้องรวมสคริปต์ภายในลำดับชั้นของอินสแตนซ์ กำหนด RunContext สำหรับแต่ละสคริปต์เพื่อลดความไม่ชัดเจนเกี่ยวกับวิธีการทำงานของมัน การตั้งค่าคุณสมบัตินี้อย่างชัดเจนทำให้โมเดลและแพ็คเกจทำงานได้อย่างถูกต้องจากตำแหน่งที่หลากหลายมากขึ้น
โครงสร้างโปรเจกต์ตัวอย่าง
โปรเจกต์อ้างอิง Plant แสดงให้เห็นว่าคุณอาจจัดระเบียบโค้ดของคุณในเกมขนาดใหญ่ที่ซับซ้อนได้อย่างไร มันเก็บโค้ดส่วนใหญ่เป็น ModuleScripts ที่สามารถนำกลับมาใช้ใหม่ได้
ตำแหน่งของสคริปต์
| Location | Description |
|---|---|
| Workspace | แทนโลก 3D ของเกม สามารถรันสคริปต์เซิร์ฟเวอร์ที่เชื่อมต่อโดยตรงกับวัตถุและควบคุมพฤติกรรมของพวกมัน |
| ReplicatedFirst | ประกอบด้วยวัตถุที่ทำซ้ำไปยังไคลเอนต์ก่อนสิ่งอื่นใด ตำแหน่งนี้เหมาะสำหรับชุดวัตถุและสคริปต์ไคลเอนต์ที่จำเป็นขั้นต่ำที่สุดในการแสดงหน้าจอโหลด |
| ReplicatedStorage | ประกอบด้วยวัตถุที่ถูกทำซ้ำไปยังทั้งไคลเอนต์และเซิร์ฟเวอร์ ตำแหน่งนี้เหมาะสำหรับ Scripts ที่มี RunContext เป็น Client, ModuleScripts ของไคลเอนต์, และ ModuleScripts ที่คุณต้องการใช้ทั้งในเซิร์ฟเวอร์และไคลเอนต์ LocalScripts จะไม่รันจากตำแหน่งนี้ |
| ServerScriptService | ประกอบด้วยสคริปต์เซิร์ฟเวอร์ ตำแหน่งนี้เหมาะสำหรับสคริปต์ที่ต้องการเข้าถึงฟังก์ชันหรือวัตถุด้านเซิร์ฟเวอร์ เช่น เกมลอจิกและการจัดเก็บข้อมูลในคลาวด์ |
| ServerStorage | ประกอบด้วยวัตถุด้านเซิร์ฟเวอร์ ตำแหน่งนี้เหมาะสำหรับวัตถุขนาดใหญ่ที่ไม่จำเป็นต้องถูกทำซ้ำไปยังไคลเอนต์ทันทีเมื่อพวกเขาเข้าร่วมเกม สคริปต์จะไม่รันจากตำแหน่งนี้ แต่คุณสามารถเก็บ ModuleScripts ด้านเซิร์ฟเวอร์ที่นี่ |
| StarterPlayer ⟩ StarterCharacterScripts | ประกอบด้วย LocalScripts ที่รันเมื่ออักขระเกิดขึ้น |
| StarterPlayer ⟩ StarterPlayerScripts | ประกอบด้วย LocalScripts ที่รันเมื่อผู้เล่นเข้าร่วมเกม |
| StarterGui | ประกอบด้วยองค์ประกอบ GUI ที่ไคลเอนต์แสดงเมื่อโหลดเกม LocalScripts สามารถรันจากตำแหน่งนี้ |
| StarterPack | โดยทั่วไปจะประกอบด้วย Tools เท่านั้น แต่ยังสามารถรวม LocalScripts สำหรับการตั้งค่ากระเป๋าเป้ของผู้เล่น |
ภาพนี้แสดงให้เห็นว่าตำแหน่งในหน้าต่าง Explorer ใดบ้างที่สามารถมีสคริปต์ของไคลเอนต์ได้ จำไว้ว่า ReplicatedFirst และ ReplicatedStorage สามารถมี Scripts ที่มี RunContext เป็น Client ในขณะที่คอนเทนเนอร์ Starter[] ควรใช้ LocalScripts
