พืช เป็นประสบการณ์อ้างอิงที่ผู้เล่นปลูกและรดน้ำเมล็ด เพื่อให้พวกเขาสามารถเก็บเกี่ยวและขายพืชผลที่ได้ในภายหลัง

โครงการมุ่งเน้นกรณีการใช้งานทั่วไปที่คุณอาจพบเมื่อพัฒนาประสบการณ์บน Robloxหากเป็นไปได้ คุณจะพบบันทึกเกี่ยวกับการแลกเปลี่ยน การยอมรับ และเหตุผลของตัวเลือกการดำเนินการต่างๆ เพื่อให้คุณสามารถตัดสินใจได้ดีที่สุดสำหรับประสบการณ์ของคุณเอง
รับไฟล์
- นําทางไปยังหน้าประสบการณ์ โรงงาน
- คลิกปุ่ม ⋯ และ แก้ไขใน Studio
ใช้กรณี
พืช ครอบคลุมกรณีการใช้งานต่อไปนี้:
- การอยู่รอดของข้อมูลเซสชันและข้อมูลผู้เล่น
- การจัดการมุมมอง UI
- เครือข่ายไคลเอนต์-เซิร์ฟเวอร์
- ประสบการณ์ผู้ใช้ครั้งแรก (FTUE)
- การซื้อเงินแข็งและเงินอ่อน
นอกจากนี้โครงการนี้แก้ปัญหาชุดที่แคบกว่าที่สามารถใช้กับประสบการณ์จํานวนมากรวมถึง:
- การปรับแต่งพื้นที่ในสถานที่ที่เกี่ยวข้องกับผู้เล่น
- การจัดการความเร็วในการเคลื่อนที่ของตัวละครผู้เล่น
- สร้างวัตถุที่ติดตามตัวอักษรไปรอบๆ
- ตรวจสอบว่าตัวละครอยู่ในส่วนใดของโลก
โปรดทราบว่ามีกรณีการใช้งานหลายกรณีในประสบการณ์นี้ที่เล็กเกินไป เฉพาะกลุ่มเกินไป หรือไม่สามารถแสดงวิธีแก้ปัญหาสำหรับความท้าทายการออกแบบที่น่าสนใจได้; เหล่านี้ไม่ได้รับการครอบคลุม
โครงสร้างโครงการ
การตัดสินใจครั้งแรกเมื่อสร้างประสบการณ์คือการตัดสินใจวิธีการจัดโครงสร้างโครงการ ซึ่งส่วนใหญ่รวมถึงสถานที่ที่จะวางตัวอย่างเฉพาะใน โมเดลข้อมูล และวิธีจัดระเบียบและโครงสร้างจุดเข้าสำหรับทั้งไคลเอนต์และรหัสเซิร์ฟเวอร์
โมเดลข้อมูล
ตารางต่อไปนี้อธิบายถึงบริการคอนเทนเนอร์ในตัวอย่างของโมเดลข้อมูลที่อยู่ใน
บริการ | ประเภทของตัวอย่าง |
---|---|
Workspace | มีโมเดลคงที่ที่แทนที่โลก 3D โดยเฉพาะอย่างยิ่งส่วนของโลกที่ไม่เป็นของผู้เล่นใดๆคุณไม่จำเป็นต้องสร้าง แก้ไข หรือทำลายตัวอย่างเหล่านี้อย่างไดนามิกในระหว่างการทำงาน ดังนั้นจึงเป็นที่ยอมรับได้ที่จะทิ้งพวกเขาไว้ที่นี่: นอกจากนี้ยังมีรูปแบบฟาร์มว่างเปล่า Folder ซึ่งจะถูกเพิ่มในระหว่างการทำงานของผู้เล่น |
Lighting | เอฟเฟกต์บรรยากาศและแสง |
ReplicatedFirst | มีส่วนย่อยเล็กที่สุดของตัวอย่างที่จำเป็นในการแสดงหน้าจอโหลดและเริ่มต้นเกมยิ่งมีตัวอย่างมากขึ้นที่ถูกวางไว้ใน ReplicatedFirst นานเท่าไรก็จะใช้เวลานานขึ้นสำหรับการซ้ำก่อนที่รหัสใน ReplicatedFirst จะสามารถทำงานได้:
|
ReplicatedStorage | ให้บริการเป็นภาชนะเก็บข้อมูลสำหรับทุกตัวอย่างที่ต้องการการเข้าถึงทั้งในไคลเอนต์และเซิร์ฟเวอร์:
|
ServerScriptService | มี Script ให้บริการเป็นจุดเข้าสำหรับโค้ดด้านเซิร์ฟเวอร์ทั้งหมดในโครงการ |
ServerStorage | ให้บริการเป็นภาชนะเก็บข้อมูลสำหรับทุกตัวอย่างที่ไม่จำเป็นต้องส่งไปยังไคลเอนต์:
|
SoundService | มีวัตถุ Sound ที่ใช้สําหรับเอฟเฟกต์เสียงในเกมภายใต้ SoundService วัตถุเหล่านี้ Sound ไม่มีตำแหน่งและไม่ถูกจำลองในพื้นที่ 3D |
จุดเข้า
โครงการส่วนใหญ่จัดระเบียบโค้ดภายในรียูสาเบิล ModuleScripts เป็นเจ้าของ สามารถใช้ซ้ำได้ แต่ไม่ได้ดำเนินการเอง; พวกเขาต้องถูกนำเข้าโดย Script หรือ LocalScriptโครงการ Roblox จำนวนมากจะมีจํานวนมากของ Script และ LocalScript วัตถุ ซึ่งแต่ละอย่างเกี่ยวข้องกับพฤติกรรมหรือระบบเฉพาะในเกม สร้างจุดเข้าหลายจุด
สำหรับเกมไมโคร พืช แบบต่างๆ จะถูกดำเนินการผ่านเดียว LocalScript ที่เป็นจุดเข้าสำหรับรหัสลูกค้าทั้งหมด และเดียว Script ที่เป็นจุดเข้าสำหรับรหัสเซิร์ฟเวอร์ทั้งหมดวิธีที่ถูกต้องสำหรับโครงการของคุณขึ้นอยู่กับความต้องการของคุณ แต่จุดเข้าเดียวให้การควบคุมมากขึ้นเกี่ยวกับลำดับที่ระบบถูกดำเนินการใน
รายการต่อไปนี้อธิบายถึงข้อแลกเปลี่ยนของทั้งสองวิธี:
- เดียว Script และเดียว LocalScript ครอบคลุมรหัสเซิร์ฟเวอร์และไคลเอนต์ตามลําดับ
- ควบคุมได้มากขึ้นเกี่ยวกับลำดับที่ระบบต่างๆ เริ่มต้นได้เพราะโค้ดทั้งหมดจะถูกเริ่มต้นจากสคริปต์เดียว
- สามารถส่งวัตถุโดยอ้างอิงระหว่างระบบได้
สถาปัตยกรรมระดับสูงของระบบ
ระบบระดับสูงในโครงการมีรายละเอียดด้านล่างระบบบางระบบมีความซับซ้อนมากกว่าระบบอื่น ๆ Classๆ

แต่ละระบบเป็น "โซลเดียน" ในที่มันเป็นคลาสที่ไม่สามารถติดตามได้ซึ่งจะถูกเริ่มต้นโดยสคริปต์เซิร์ฟเวอร์หรือไคลเอนต์ที่เกี่ยวข้อง start แทนคุณสามารถอ่านเพิ่มเติมเกี่ยวกับรูปแบบ โซลเดียน ในภายหลังในคู่มือนี้
เซิร์ฟเวอร์
ระบบต่อไปนี้เกี่ยวข้องกับเซิร์ฟเวอร์
ระบบ | คําอธิบาย |
---|---|
เครือข่าย |
|
เซิร์ฟเวอร์ข้อมูลผู้เล่น |
|
ตลาด |
|
ผู้จัดการกลุ่มการชนกัน | กำหนดโมเดลตัวละครผู้เล่นให้กับกลุ่มการชนกัน .:
|
เซิร์ฟเวอร์จัดการฟาร์ม |
|
คอนเทนเนอร์วัตถุผู้เล่น |
|
ผู้เล่นแท็ก |
|
เซิร์ฟเวอร์ FtueManager |
|
ตัวสร้างตัวละคร |
|
ไคลเอนต์
ระบบต่อไปนี้เกี่ยวข้องกับไคลเอนต์
ระบบ | คําอธิบาย |
---|---|
เครือข่าย |
|
ผู้เล่นข้อมูลลูกค้า |
|
ลูกค้าตลาด |
|
ผู้จัดการกระโดด LocalWalk |
|
ไคลเอนต์ผู้จัดการฟาร์ม |
|
การตั้งค่า UI |
|
ไคลเอนต์ FtueManager |
|
การวิ่งตัวละคร |
|
การสื่อสารระหว่างไคลเอนต์-เซิร์ฟเวอร์
ประสบการณ์ Roblox ส่วนใหญ่มีบางองค์ประกอบของการสื่อสารระหว่างไคลเอนต์และเซิร์ฟเวอร์สิ่งนี้สามารถรวมถึงคำขอของไคลเอนต์ที่ร้องขอให้เซิร์ฟเวอร์ดำเนินการด้วยการกระทำบางอย่างและเซิร์ฟเวอร์สำรองการอัปเดตให้กับไคลเอนต์
ในโครงการนี้การสื่อสารระหว่างไคลเอนต์และเซิร์ฟเวอร์จะถูกเก็บไว้ให้เป็นทั่วไปมากที่สุดโดยการจำกัดการใช้งานของ RemoteEvent และ RemoteFunction วัตถุเพื่อลดปริมาณกฎพิเศษที่ต้องติดตามโครงการนี้ใช้วิธีต่อไปนี้ตามลําดับความชอบ:
การเลียนแบบผ่านระบบข้อมูลผู้เล่น
ระบบข้อมูลผู้เล่น สามารถระบุข้อมูลที่เกี่ยวข้องกับผู้เล่นซึ่งยังคงอยู่ระหว่างเซสชันการบันทึก ระบบนี้ให้การเลียนแบบจากไคลเอนต์ไปยังเซิร์ฟเวอร์และชุดของ API ที่สามารถใช้เพื่อสอบถามข้อมูลและสมัครรับการเปลี่ยนแปลง ทำให้เหมาะสำหรับการเลียนแบบการเปลี่ยนแปลงสถานะผู้เล่นจากเซิร์ฟเวอร์ไปยังไคลเอนต์
ตัวอย่างเช่น แทนที่จะยิง bespoke UpdateCoins``Class.RemoteEvent เพื่อบอกลูกค้าว่ามีเหรียญกี่อัน คุณสามารถโทรไปที่สิ่งต่อไปนี้และให้ลูกค้าสมัครรับผ่านเหตุการณ์ PlayerDataClient.updated
PlayerDataServer:setValue(player, "coins", 5)
แน่นอนนี่มีประโยชน์เฉพาะสำหรับการเลียนแบบจากเซิร์ฟเวอร์ไปยังไคลเอนต์และสำหรับค่าที่คุณต้องการให้ยังคงอยู่ระหว่างเซสชัน แต่สิ่งนี้ใช้กับจำนวนเคสที่น่าประหลาดใจในโครงการรวมถึง:
- ขั้นตอน FTUE ปัจจุบัน
- คลังไอเท็ม
- จํานวนเหรียญที่ผู้เล่นมี
- สถานะฟาร์มของผู้เล่น
การเลียนแบบผ่านคุณสมบัติ
ในสถานการณ์ที่เซิร์ฟเวอร์ต้องส่งค่าที่กําหนดเองไปยังไคลเอนต์ที่เฉพาะเจาะจงสําหรับ Instance คุณสามารถใช้ คุณลักษณะRoblox จะสร้างค่าตัวละครที่ซ้ำกันโดยอัตโนมัติ ดังนั้นคุณจึงไม่จำเป็นต้องรักษาเส้นทางโค้ดใดๆ เพื่อสร้างสถานะที่เกี่ยวข้องกับวัตถุประโยชน์อีกประการหนึ่งคือการสําเนานี้เกิดขึ้นพร้อมกับตัวอินสแตนซ์เอง
เป็นประโยชน์อย่างยิ่งสำหรับตัวอย่างที่สร้างขึ้นในเวลาทำงาน เนื่องจากคุณสมบัติที่กำหนดไว้ในตัวอย่างใหม่ก่อนที่จะถูกส่งต่อไปยังโมเดลข้อมูลจะถูกสร้างขึ้นอย่างโดดเด่นด้วยตัวอย่างเองสิ่งนี้ข้ามความจำเป็นในการเขียนโค้ดเพื่อ "รอ" ข้อมูลเพิ่มเติมจะถูกสําเนาผ่าน RemoteEvent หรือ StringValue
คุณยังสามารถอ่านคุณสมบัติโดยตรงจากโมเดลข้อมูลได้จากไคลเอนต์หรือเซิร์ฟเวอร์โดยตรงด้วยวิธี GetAttribute() และสมัครรับการเปลี่ยนแปลงด้วยวิธี GetAttributeChangedSignal()ในโครงการ โรงงาน วิธีนี้จะถูกใช้เพื่อ, ในหมู่สิ่งอื่น ๆ, สําหรับการสําเนาสถานะปัจจุบันของพืชให้กับลูกค้า
การเลียนแบบผ่านแท็ก
CollectionService ช่วยให้คุณสามารถใช้แท็กสตริงกับ Instance ได้ ซึ่งมีประโยชน์สำหรับการจัดหมวดหมู่ตัวอย่างและการเลียนแบบการจัดหมวดหมู่นั้นไปยังไคลเอนต์
ตัวอย่างเช่น แท็ก CanPlant ถูกใช้บนเซิร์ฟเวอร์เพื่อสื่อสารกับไคลเอนต์ว่าหม้อที่กำหนดให้สามารถรับพืชได้
ส่งข้อความโดยตรงผ่านโมดูลเครือข่าย
สำหรับสถานการณ์ที่ไม่มีตัวเลือกก่อนหน้าใดที่ใช้ได้ คุณสามารถใช้การโทรเครือข่ายแบบกําหนดเองผ่านโมดูล เครือข่าย นี่คือตัวเลือกเดียวในโครงการที่อนุญาตให้มีการสื่อสารระหว่างไคลเอนต์และเซิร์ฟเวอร์ และดังนั้นจึงมีประโยชน์มากที่สุดสำหรับการส่งคำขอของไคลเอนต์และรับการตอบสนองจากเซิร์ฟเวอร์
พืช ใช้การโทรเครือข่ายโดยตรงสำหรับคำขอของลูกค้าหลากหลายรวมถึง:
- รดน้ำต้นไม้
- ปลูกเมล็ด
- ไอเท็ม
ข้อเสียของวิธีนี้คือแต่ละข้อความจะต้องมีการกำหนดค่าแบบเฉพาะที่อาจเพิ่มความซับซ้อนของโครงการ แม้ว่าจะหลีกเลี่ยงได้ทุกที่ที่เป็นไปได้ โดยเฉพาะอย่างยิ่งสำหรับการสื่อสารจากเซิร์ฟเวอร์ไปยังไคลเอนต์
คลาสและซิงเลตอน
คลาสในโครงการ พืช สามารถสร้างและทำลายได้เหมือนตัวอย่างบน Robloxคําสั่งของคลาสได้รับแรงบันดาลใจจากวิธีการ Lua ที่ไอดิโอมาตรฐานสําหรับการเขียนโปรแกรมแบบเป้าหมาย กับการเปลี่ยนแปลงหลายอย่างเพื่อเปิดใช้งานการตรวจสอบประเภทอย่างเคร่งครัด โดยมีการเปลี่ยนแปลงหลายอย่างเพื่อเปิดใช้งานการตรวจสอบประเภทอย่างเคร่งครัด
การสร้างทันที
หลายคลาสในโครงการมีความสัมพันธ์กับหนึ่งหรือมากกว่า Instancesวัตถุของคลาสที่กำหนดได้ถูกสร้างโดยใช้วิธี new() ในการสร้างตัวอย่างที่สอดคล้องกับวิธีที่ตัวอย่างถูกสร้างใน Roblox โดยใช้ Instance.new()
ลายนี้มักใช้สำหรับวัตถุที่คลาสมีการแสดงอย่างกายภาพในโมเดลข้อมูลและคลาสขยายฟังก์ชันของมันตัวอย่างที่ดีคือ ซึ่งสร้างวัตถุ ระหว่างสองวัตถุที่กำหนดไว้และเก็บการแนบประกอบให้หันไปทางขึ้นเสมอตัวอย่างเหล่านี้สามารถคลอนจากรุ่นสำเร็จรูปใน ReplicatedStorage หรือส่งไปยัง new() ในฐานะอาร์กิวเมนต์และเก็บไว้ภายในวัตถุภายใต้ self
ตัวอย่างที่ตรงกัน
ตามที่ระบุไว้ข้างต้น หลายคลาสในโครงการนี้มีการแทนที่โมเดลข้อมูล ตัวอย่างที่ตรงกับคลาสและถูกควบคุมโดยมัน
แทนที่จะสร้างตัวอย่างเหล่านี้เมื่อวัตถุคลาสถูกสร้างขึ้น โค้ดมักจะเลือกที่จะ Clone() เวอร์ชันสำเร็จรูปของ Instance ที่เก็บไว้ภายใต้ ReplicatedStorage หรือ ServerStorageแม้ว่าจะเป็นไปได้ที่จะเซริฟิกคุณสมบัติของตัวอย่างเหล่านี้และสร้างขึ้นจากเปล่าในฟังก์ชันของคลาส new() การทำเช่นนั้นจะทำให้การแก้ไขวัตถุยากมากและทำให้พวกเขายากต่อการอ่านสําหรับผู้อ่านนอกจากนี้การโคลนนิ่งตัวอย่างโดยทั่วไปเป็นการดำเนินการที่เร็วกว่าการสร้างตัวอย่างใหม่และปรับแต่งคุณสมบัติในเวลาเรียกใช้
การรวม
แม้ว่าการมรดกจะเป็นไปได้ใน Luau โดยใช้ metatables แต่โครงการเลือกที่จะอนุญาตให้คลาสสามารถขยายตัวกันผ่าน composition เมื่อรวมชั้นผ่านการสร้างขึ้น วัตถุ "ลูก" จะถูกสร้างขึ้นในวิธี new() ของคลาสและรวมอยู่ในฐานะสมาชิกภายใต้ self
สำหรับตัวอย่างนี้ในการดำเนินการดูที่คลาส CloseButton ซึ่งห่อหุ้มคลาส Button
ทำความสะอาด
คล้ายกับวิธีที่ Instance สามารถถูกทําลายได้ด้วยวิธี Destroy() คลาสที่สามารถสร้างได้ก็สามารถถูกทําลายได้เช่นกันวิธีการทำลายสำหรับคลาสโครงการคือ ด้วยตัวอักษรเล็ก สำหรับความสอดคล้องของคลาสในโค้ดทั้งหมดรวมถึงการแยกแยะระหว่างคลาสโครงการและ Roblox ตัวอย่าง นอกจากนี้ยังใช้เพื่อแยกแยะระหว่างคลาสในโค้ดของโครงการและ Roblox ตัวอย่าง
บทบาทของวิธี destroy() คือการทำลายตัวอย่างใดๆ ที่สร้างขึ้นโดยวัตถุ ตัดการเชื่อมต่อทั้งหมด และเรียก destroy() บนวัตถุลูกใดๆเป็นสิ่งสำคัญเป็นพิเศษสำหรับการเชื่อมต่อเพราะตัวอย่างที่มีการเชื่อมต่อที่ใช้งานไม่ถูกล้างโดยตัวรวบรวมขยะ Luau แม้ว่าจะไม่มีการอ้างอิงถึงตัวอย่างหรือการเชื่อมต่อกับตัวอย่างยังคงอยู่ก็ตาม
ซิงเลตอน
ซิงเลตัน ตามที่ชื่อบ่งบอก เป็นคลาสที่มีเพียงวัตถุเดียวเท่านั้นที่สามารถมีอยู่ได้พวกเขาเป็นเทียบเท่าของบริการของ Roblox .แทนที่จะเก็บการอ้างอิงถึงวัตถุสิงเกิลและส่งมันไปรอบๆ ในรหัส Luau พืช ใช้ประโยชน์จากความจริงที่ต้องการให้แคช ModuleScript คืนค่าที่ส่งกลับซึ่งหมายความว่าการต้องการ singleton เดียวกัน ModuleScript จากสถานที่ต่างๆ อย่างสม่ำเสมอจะให้วัตถุที่ส่งคืนเดียวกันข้อยกเว้นเดียวสำหรับกฎนี้จะเกิดขึ้นหากสภาพแวดล้อมที่แตกต่างกัน (ไคลเอนต์หรือเซิร์ฟเวอร์) เข้าถึง ModuleScript
ซิงเลตันแตกต่างจากคลาสที่ไม่เสถียรโดยความจริงที่ว่าพวกเขาไม่มีวิธี new() เมธอดแทนที่จะส่งวัตถุพร้อมกับวิธีการและสถานะของมันกลับโดยตรงผ่าน ModuleScriptเนื่องจากไม่มีการสร้างสิงเลตอน จึงไม่มีการใช้สัญลักษณ์ self และวิธีการจะถูกเรียกแทนด้วยจุลภาค ( . ) แทนที่จะใช้จุลภาค ( : )
การตรวจสอบประเภทที่เคร่งครัด
Luau สนับสนุนการพิมพ์แบบค่อยเป็นค่อยไปซึ่งหมายความว่าคุณสามารถเพิ่มการกำหนดประเภททางเลือกให้กับบางหรือทั้งหมดของโค้ดของคุณได้ในโครงการนี้ strict การตรวจสอบรูปแบบจะถูกใช้สำหรับทุกสคริปต์นี่เป็นตัวเลือกที่อนุญาตน้อยที่สุดสำหรับเครื่องมือวิเคราะห์สคริปต์ของ Roblox และดังนั้นจึงมีโอกาสมากที่สุดที่จะจับข้อผิดพลาดประเภทก่อนที่จะรัน
คําสั่งประเภทคลาส
วิธีที่กำหนดไว้ในการสร้างคลาสใน Lua คือ เอกสารได้ดี แต่ไม่เหมาะกับการพิมพ์ Luau ที่แข็งแกร่งใน Luau วิธีที่ง่ายที่สุดในการรับประเภทของคลาสคือวิธี typeof() :
type ClassType = typeof(Class.new())
สิ่งนี้ทำงานได้ แต่ไม่มีประโยชน์มากเมื่อคลาสของคุณเริ่มด้วยค่าที่มีอยู่เฉพาะในเวลาทำงาน เช่น Player วัตถุนอกจากนี้สมมติฐานที่ทำในภาษา Lua คลาสสัญญาณเป็นว่าการประกาศวิธีบนคลาส self จะเป็นตัวอย่างของคลาสนั้นเสมอ; นี่ไม่ใช่สมมติฐานที่เครื่องแปลประเภทสามารถทำได้
เพื่อสนับสนุนการตรวจสอบประเภทที่เคร่งครัด โครงการ พืช ใช้การแก้ปัญหาที่แตกต่างจากภาษา Lua คลาสสัญญาณในหลายวิธี ซึ่งบางส่วนอาจรู้สึกไม่ชัดเจน:
- การจำแนกประเภทของ self ถูกซ้ำกันทั้งในคําประกาศประเภทและในตัวสร้างสิ่งนี้ทำให้เกิดภาระในการบำรุงรักษา แต่คําเตือนจะถูกธงถ้าสองคํานิยามล้มออกจากการซิงค์กัน
- วิธีการในคลาสจะถูกประกาศด้วยจุลภาคจึงสามารถประกาศได้โดยเฉพาะว่าเป็นประเภท วิธียังคงสามารถเรียกได้ด้วยเครื่องหมายจุลภาคตามที่คาดไว้
--!เคร่งครัด
local MyClass = {}
MyClass.__index = MyClass
export type ClassType = typeof(setmetatable(
{} :: {
property: number,
},
MyClass
))
function MyClass.new(property: number): ClassType
local self = {
property = property,
}
setmetatable(self, MyClass)
return self
end
function MyClass.addOne(self: ClassType)
self.property += 1
end
return MyClass
ประเภทการโค้งหลังการป้องกันทางเหตุผล
ในเวลาของการเขียน, ประเภทของค่าจะไม่ถูกจำกัดหลังจากคําสั่งเงื่อนไขการป้องกันตัวอย่างเช่น หลังจากปฏิบัติตามยามด้านล่าง ประเภทของ optionalParameter จะไม่ถูกจำกัดเป็น number
--!เคร่งครัด
local function foo(optionalParameter: number?)
if not optionalParameter then
return
end
print(optionalParameter + 1)
end
เพื่อลดปัญหานี้ จะสร้างตัวแปรใหม่หลังจากผู้พิทักษ์เหล่านี้ด้วยประเภทที่ชัดเจน
--!เคร่งครัด
local function foo(optionalParameter: number?)
if not optionalParameter then
return
end
local parameter = optionalParameter :: number
print(parameter + 1)
end
ข้ามโครงสร้างชั้นของ DataModel
ในบางกรณี รหัสฐานจำเป็นต้องเดินทางผ่านห่วงโซ่ของโมเดลข้อมูลของต้นไม้ของวัตถุที่สร้างขึ้นในเวลารันไทม์นี่เป็นความท้าทายที่น่าสนใจสำหรับการตรวจสอบประเภทในเวลาของการเขียน ไม่สามารถกำหนดลำดับชั้นของโมเดลข้อมูลทั่วไปเป็นประเภทได้ผลที่ตามมาคือกรณีที่มีเพียงประเภทข้อมูลเดียวที่มีอยู่สำหรับโครงสร้างข้อมูลรูปแบบคือประเภทของตัวอย่างระดับสูง
วิธีหนึ่งในการเผชิญความท้าทายนี้คือการโค้งถึง any แล้วปรับแต่ง ตัวอย่างเช่น:
local function enableVendor(vendor: Model)
local zonePart: BasePart = (vendor :: any).ZonePart
end
ปัญหาของวิธีนี้คือมันส่งผลต่อการอ่านได้ เนื่องจากมันส่งผลต่อการอ่านได้แทนที่โครงการใช้โมดูลทั่วไปชื่อว่า getInstance สำหรับการเดินทางผ่านชั้นวาระของโมเดลข้อมูลที่โยนไปยัง any ภายใน
local function enableVendor(vendor: Model)
local zonePart: BasePart = getInstance(vendor, "ZonePart")
end
เมื่อความเข้าใจของเครื่องประเภทเกี่ยวกับโมเดลข้อมูลพัฒนาขึ้น ก็เป็นไปได้ว่ารูปแบบเช่นนี้จะไม่จำเป็นอีกต่อไป
อินเทอร์เฟซผู้ใช้
โรงงาน รวมถึงอินเทอร์เฟซผู้ใช้ 2D ที่ซับซ้อนและง่ายหลากหลายซึ่งรวมถึงไอเทมหน้าจอแสดงข้อมูลที่ไม่สามารถโต้ตอบได้ (HUD) เลือกซื้อ
วิธีการ UI
คุณสามารถเปรียบเทียบ Roblox UI กับ HTML DOM ได้อย่างหลวมๆ เพราะเป็นลำดับของวัตถุที่อธิบายถึงสิ่งที่ผู้ใช้ควรเห็นวิธีการสร้างและอัปเดตอินเทอร์เฟซผู้ใช้ Roblox แบ่งออกเป็น 2 ประเภทใหญ่คือ บังคับ และ ประกาศ การปฏิบัติ
วิธีการ | ข้อดีและข้อเสีย |
---|---|
บังคับ | ในการออกแบบแบบบังคับ UI จะได้รับการปฏิบัติเหมือนกับลำดับชั้นอินสแตนซ์อื่นๆ บน Robloxโครงสร้าง UI จะถูกสร้างก่อนที่จะรันใน Studio และเพิ่มลงในโมเดลข้อมูลโดยปกติโดยตรงใน StarterGuiจากนั้นในระหว่างการทำงานรหัสจะดัดแปลงชิ้นส่วนเฉพาะของ UI เพื่อสะท้อนสถานะที่ผู้สร้างต้องการ: วิธีนี้มาพร้อมกับข้อดีบางอย่างคุณสามารถสร้าง UI จากเปล่าใน Studio และเก็บไว้ในโมเดลข้อมูลนี่คือประสบการณ์การแก้ไขที่เรียบง่ายและมีภาพที่สามารถเร่งการสร้าง UI ได้เนื่องจากรหัส UI ที่จําเป็นต้องใช้เพียงกังวลกับสิ่งที่ต้องเปลี่ยนแปลงเท่านั้น จึงทำให้การเปลี่ยนแปลง UI ง่ายๆ เป็นไปได้: ข้อเสียที่สำคัญคือ เนื่องจากการออกแบบ UI ที่จําเป็นต้องใช้สถานะในรูปแบบของการเปลี่ยนแปลง การแสดงอธิบายสถานะที่ซับซ้อนจึงยากมากที่จะค้นหาและแก้ไขเป็นเรื่องธรรมดาที่ข้อผิดพลาดจะเกิดขึ้นเมื่อพัฒนารหัส UI ที่จําเป็น โดยเฉพาะอย่างยิ่งเมื่อสถานะและ UI กลายเป็นไม่สอดคล้องเนื่องจากการอัปเดตหลายรายการที่โต้ตอบในลําดับที่ไม่คาดคิด: ความท้าทายอีกอย่างหนึ่งด้วยวิธีการที่มีความจำเป็นคือการที่ยากที่จะแยกส่วน UI ให้เป็นส่วนที่มีความหมายที่สามารถประกาศได้ครั้งเดียวและนำมาใช้ซ้ำได้เนื่องจากต้นไม้ UI ทั้งหมดถูกประกาศในเวลาแก้ไขจึงอาจมีลายทั่วไปซ้ำในหลายส่วนของโมเดลข้อมูลได้ |
ประกาศ | ในการอนุกรมแบบเรียกใช้ สถานะที่ต้องการของตัวอย่าง UI จะถูกประกาศอย่างชัดเจน และการดำเนินการที่มีประสิทธิภาพของสถานะนี้จะถูกแยกออกโดยไลบรารีเช่น Roact หรือ Fusion: ข้อดีของวิธีนี้คือการใช้งานของสถานะกลายเป็นเรื่องง่ายและคุณต้องอธิบายสิ่งที่คุณต้องการให้ UI ดูเหมือนเท่านั้นสิ่งนี้ทำให้การระบุและแก้ไขข้อบกพร่องง่ายขึ้นอย่างมาก: ข้อเสียหลักคือต้องประกาศต้นไม้ UI ทั้งหมดในรหัสห้องสมุดเช่น Roact และ Fusion มีสัญลักษณ์เพื่อทำให้ง่ายขึ้น แต่ก็ยังคงเป็นกระบวนการที่ใช้เวลานานและประสบการณ์การแก้ไขที่น้อยกว่าเมื่อสร้าง UI |
พืช ใช้วิธีการ บังคับ ภายใต้แนวคิดที่แสดงการเปลี่ยนแปลงโดยตรงจะให้ภาพรวมที่มีประสิทธิภาพมากขึ้นของวิธีที่ UI ถูกสร้างและจัดการบน Robloxจะไม่เป็นไปได้ด้วยวิธีการแบบเรียกใช้โครงสร้างและโลจิสติกที่ซ้ำซากบางอย่างยังถูกสังเคราะห์เป็นส่วนประกอบที่ใช้ซ้ำได้ เพื่อหลีกเลี่ยงจุดบกพร่องทั่วไปในการออกแบบ UI ที่บังคับ
สถาปัตยกรรมระดับสูง

ชั้นและส่วนประกอบ
ใน พืช ทั้งหมด UI จะเป็น Layer หรือ Component
- Layer กำหนดเป็นกลุ่มระดับสูงที่รวบรวมโครงสร้าง UI สำเร็จรูปใน ReplicatedStorageชั้นอาจมีส่วนประกอบหลายอย่าง หรืออาจบรรจุโลจิสต์ของตัวเองทั้งหมดตัวอย่างของชั้นคือเมนูสินค้าคงคลังหรือตัวบ่งบอกจํานวนเหรียญในการแสดงผลด้านบน
- Component เป็นองค์ประกอบ UI ที่ใช้ซ้ำได้เมื่อวัตถุส่วนประกอบใหม่ถูกสร้างขึ้น มันจะโคลนต้นแบบเทมเพลตจาก ReplicatedStorageส่วนประกอบอาจมีส่วนประกอบอื่นอยู่ภายในตัวเองตัวอย่างของส่วนประกอบคือคลาสปุ่มทั่วไปหรือแนวคิดของรายการที่อยู่ในรายการ
ดูการจัดการ
ปัญหาการจัดการ UI ทั่วไปคือการจัดการมุมมองโครงการนี้มีเมนูและรายการ HUD หลายรายการซึ่งบางรายการฟังการใส่ข้อมูลของผู้ใช้และจำเป็นต้องจัดการอย่างระมัดระวังเมื่อพวกเขาปรากฏหรือเปิดใช้งาน
พืช เข้าใกล้ปัญหานี้ด้วยระบบ UIHandler ซึ่งจัดการเมื่อชั้น UI ควรหรือไม่ควรปรากฏให้เห็นชั้น UI ทั้งหมดในเกมจะถูกจัดหมวดหมู่เป็น HUD หรือ Menu และการมองเห็นของพวกเขาจะได้รับการจัดการโดยกฎต่อไปนี้:
- สถานะที่เปิดใช้งานของ Menu และ HUD ชั้นสามารถสลับได้
- ชั้นที่เปิดใช้งาน HUD จะแสดงเฉพาะถ้าไม่มีชั้น Menu ถูกเปิดใช้งาน
- ชั้นที่เปิดใช้งาน Menu จะถูกเก็บไว้ในกอง และชั้น Menu เดียวเท่านั้นที่ปรากฏในแต่ละครั้งเมื่อชั้น Menu ถูกเปิดใช้งาน มันจะถูกสอดเข้าไปในด้านหน้าของกองและแสดงเมื่อชั้น Menu ถูกปิดใช้งาน มันจะถูกลบออกจากกองและชั้นถัดไปที่เปิดใช้งานได้ Menu ในคิวจะแสดงขึ้น
วิธีนี้ใช้งานได้ง่ายเพราะช่วยให้สามารถนําทางเมนูด้วยประวัติได้หากเปิดเมนูหนึ่งจากเมนูอื่น การปิดเมนูใหม่จะแสดงเมนูเก่าอีกครั้ง
ชั้นส่วนตัวของ UI ลงทะเบียนตัวเองกับ UIHandler และได้รับสัญญาณที่จะยิงเมื่อเปลี่ยนวิสัยทัศน์ของมัน
อ่านต่อ
จากภาพรวมที่ละเอียดของโครงการ พืช คุณอาจต้องการสำรวจคู่มือต่อไปนี้ซึ่งไปลึกในเรื่องแนวคิดและหัวข้อที่เกี่ยวข้อง
- โมเดลไคลเอนต์-เซิร์ฟเวอร์ — ภาพรวมของโมเดลไคลเอนต์-เซิร์ฟเวอร์ใน Roblox
- อีเวนต์ระยะไกลและการโทรกลับ — ทั้งหมดเกี่ยวกับอีเวนต์เครือข่ายระยะไกลและการโทรกลับสำหรับการสื่อสารข้ามเส้นแบ่งไคลเอนต์-เซิร์ฟเวอร์
- UI — รายละเอียดเกี่ยวกับวัตถุอินเทอร์เฟซผู้ใช้และการออกแบบบน Roblox