ปรับปรุงประสิทธิภาพ

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

หน้านี้อธิบายปัญหาประสิทธิภาพทั่วไปและแนวทางปฏิบัติที่ดีที่สุดในการบรรเทาปัญหาเหล่านั้น

การคำนวณสคริปต์

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

ปัญหาทั่วไป

  • การดำเนินการที่เข้มข้นบนโครงสร้างตาราง - การดำเนินการที่ซับซ้อน เช่น การจัดรูปแบบ, การย้อนกลับรูปแบบ, และการทำสำเนาลึก มีค่าใช้จ่ายด้านประสิทธิภาพสูง โดยเฉพาะอย่างยิ่งในโครงสร้างตารางขนาดใหญ่ ซึ่งเป็นจริงโดยเฉพาะถ้าการดำเนินการเหล่านี้มีการวนซ้ำหรือเกี่ยวข้องกับการวนซ้ำในโครงสร้างข้อมูลที่มีขนาดใหญ่มาก

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

การบรรเทา

  • เรียกใช้โค้ดในเหตุการณ์ของ RunService อย่างประหยัด โดยจำกัดการใช้งานไว้ในกรณีที่การเรียกซ้ำความถี่สูงเป็นสิ่งสำคัญ (เช่น การอัปเดตกล้อง) คุณสามารถทำงานโค้ดส่วนใหญ่ในเหตุการณ์อื่นหรือทำซ้ำในลูปในระยะเวลาที่น้อยลง
  • แบ่งงานขนาดใหญ่หรือมีค่าใช้จ่ายสูงโดยใช้ task.wait() เพื่อกระจายงานไปยังเฟรมหลายๆ เฟรม
  • ระบุและปรับแต่งการดำเนินการที่มีค่าใช้จ่ายไม่จำเป็น และใช้ มัลติ เธรดดิ้ง สำหรับงานที่มีค่าใช้จ่ายสูงที่ไม่จำเป็นต้องเข้าถึงโมเดลข้อมูล
  • สคริปต์บางตัวที่อยู่ฝั่งเซิร์ฟเวอร์สามารถได้รับประโยชน์จาก การสร้างโค้ดแบบเนทีฟ ซึ่งเป็นธงง่ายๆ ที่คอมไพล์สคริปต์เป็นโค้ดเครื่องแทนที่จะเป็นไบต์โค้ด

ขอบเขตของ MicroProfiler

ขอบเขตการคำนวณที่เกี่ยวข้อง
RunService.PreRenderโค้ดที่ดำเนินการในเหตุการณ์ PreRender
RunService.PreSimulationโค้ดที่ดำเนินการในเหตุการณ์ Stepped
RunService.PostSimulationโค้ดที่ดำเนินการในเหตุการณ์ Heartbeat
RunService.Heartbeatโค้ดที่ดำเนินการในเหตุการณ์ Heartbeat

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการดีบั๊กสคริปต์โดยใช้ MicroProfiler โปรดดูที่ไลบรารี debug ซึ่งรวมฟังก์ชันสำหรับการแท็กโค้ดเฉพาะและเพิ่มความเฉพาะเจาะจง อย่างเช่น debug.profilebegin และ debug.profileend วิธีการของ Roblox API หลายรายการที่ถูกเรียกโดยสคริปต์ยังมีแท็ก MicroProfiler ที่เกี่ยวข้องซึ่งสามารถให้ข้อมูลสัญญาณที่มีประโยชน์ได้

การใช้หน่วยความจำของสคริปต์

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

ค่าหน่วยความจำด้านล่างใน Developer Console อาจบ่งชี้ถึงปัญหาที่ต้องการการตรวจสอบเพิ่มเติม:

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

ปัญหาทั่วไป

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

  • ตาราง - การเพิ่มวัตถุลงในตารางแต่ไม่ลบเมื่อไม่จำเป็นอีกต่อไปทำให้ใช้หน่วยความจำโดยไม่จำเป็น โดยเฉพาะสำหรับตารางที่ติดตามข้อมูลผู้ใช้เมื่อพวกเขาเข้าร่วม ตัวอย่างเช่น โค้ดตัวอย่างดังต่อไปนี้สร้างตารางเพื่อเพิ่มข้อมูลผู้ใช้ทุกครั้งที่ผู้ใช้เข้าร่วม:

    ตัวอย่าง
    local playerInfo = {}
    Players.PlayerAdded:Connect(function(player)
    playerInfo[player] = {} -- ข้อมูลบางอย่าง
    end)

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

การบรรเทา

เพื่อทำความสะอาดค่าทั้งหมดที่ใช้เพื่อป้องกันการรั่วไหลของหน่วยความจำ:

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

    • ยกเลิกการเชื่อมต่อด้วยมือโดยใช้ฟังก์ชัน Disconnect()
    • ทำลายอินสแตนซ์ที่เหตุการณ์เป็นของอยู่ด้วยฟังก์ชัน Destroy()
    • ทำลายวัตถุสคริปต์ที่การเชื่อมต่อเชื่อมโยงอยู่
  • ลบวัตถุผู้เล่นและตัวละครหลังจากการออก - เปิดใช้งาน Workspace.PlayerCharacterDestroyBehavior เพื่อทำลายวัตถุผู้เล่นและโมเดลตัวละครโดยอัตโนมัติหลังจากผู้ใช้ออก หากคุณต้องการคุณสามารถทำความสะอาดพวกเขาได้ด้วยตนเอง:

    ตัวอย่างการทำความสะอาดผู้เล่นและตัวละคร
    local Players = game:GetService("Players")
    Players.PlayerAdded:Connect(function(player)
    player.CharacterRemoving:Connect(function(character)
    task.defer(character.Destroy, character)
    end)
    end)
    Players.PlayerRemoving:Connect(function(player)
    task.defer(player.Destroy, player)
    end)

การคำนวณฟิสิกส์

การจำลองฟิสิกส์ที่มากเกินไปอาจเป็นสาเหตุหลักของเวลาคำนวณที่เพิ่มขึ้นต่อเฟรมทั้งในฝั่งเซิร์ฟเวอร์และลูกค้า

ปัญหาทั่วไป

  • ความถี่เวลาของฟิสิกส์ที่สูงเกินไป - โดยค่าเริ่มต้น พฤติกรรมการก้าวใน โหมดปรับเปลี่ยน ซึ่งฟิสิกส์จะก้าวที่ 60 Hz, 120 Hz, หรือ 240 Hz ขึ้นอยู่กับความซับซ้อนของกลไกฟิสิกส์

    โหมดที่คงที่ซึ่งมีความแม่นยำในการฟิสิกส์ที่ดีขึ้นยังมีให้ซึ่ง บังคับให้ฟิสิกส์ทั้งหมดก้าวที่ 240 Hz (สี่ครั้งต่อเฟรม) สิ่งนี้ส่งผลให้มีการคำนวณมากขึ้นอย่างมีนัยสำคัญในทุกๆ เฟรม

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

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

การบรรเทา

  • ยึดชิ้นส่วนที่ไม่ต้องการการจำลอง - ยึดชิ้นส่วนทั้งหมดที่ไม่จำเป็นต้องถูกขับเคลื่อนด้วยฟิสิกส์ เช่น สำหรับ NPC ที่คงที่

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

  • ลดความซับซ้อนของกลไก

    • ตามที่เป็นไปได้ ลดจำนวนข้อกำหนดหรือข้อต่อฟิสิกส์ในกลไก
    • ลดจำนวนการชนกันในกลไก เช่น โดยการใช้ขีดจำกัดหรือลิมิตการชนกันเพื่อไม่ให้ส่วนต่างๆ ชนกัน
  • ลดการใช้ความแม่นยำในการตรวจจับการชนกันของเมซ

    • สำหรับวัตถุขนาดเล็กหรือไม่สามารถติดต่อได้ ซึ่งผู้ใช้อาจไม่สังเกตเห็นความแตกต่าง ใช้ความแม่นยำของช่อง

    • สำหรับวัตถุขนาดเล็กถึงขนาดกลาง ใช้ความแม่นยำของช่องหรือช่วง ตามรูปร่าง

    • สำหรับวัตถุขนาดใหญ่และซับซ้อนมาก สร้างการชนกันเองโดยใช้อินสแตนซ์ที่มองไม่เห็นเมื่อต้องทำ

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

    • คุณสามารถแสดงเรขาคณิตการชนกันเพื่อการดีบั๊กใน Studio โดยเปิด Collision fidelity จาก Visualization Options ซึ่งอยู่มุมขวาบนของ 3D viewport

      นอกจากนี้ คุณยังสามารถใช้ฟิลเตอร์ CollisionFidelity=PreciseConvexDecomposition กับ Explorer ซึ่งจะแสดงจำนวนของชิ้นส่วนเมซที่มีความแม่นยำและช่วยให้คุณเลือกได้ง่าย

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

ขอบเขตของ MicroProfiler

ขอบเขตการคำนวณที่เกี่ยวข้อง
physicsSteppedการคำนวณฟิสิกส์โดยรวม
worldStepการก้าวฟิสิกส์ที่ดำเนินการในแต่ละเฟรม

การใช้หน่วยความจำฟิสิกส์

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

ปัญหาทั่วไป

โหมดการตรวจจับการชนกันเริ่มต้นและแม่นยำใช้หน่วยความจำสูงกว่าค่าสองโหมดอื่น ๆ ที่มีรูปร่างการชนกันที่มีความแม่นยำต่ำกว่า

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

วิธีการบรรเทา

เพื่อลดหน่วยความจำที่ใช้สำหรับความแม่นยำของการชนกัน:

  • สำหรับชิ้นส่วนที่ไม่ต้องการการชนกัน ปิดการชนกันโดยการตั้งค่า BasePart.CanCollide, BasePart.CanTouch และ BasePart.CanQuery เป็น false
  • ลดความแม่นยำของการชนโดยการตั้งค่าของ CollisionFidelity โหมด Box มีค่าใช้จ่ายหน่วยความจำต่ำสุด และ Default และ Precise โดยทั่วไปมีค่าใช้จ่ายสูงกว่า
    • โดยทั่วไปปลอดภัยที่จะตั้งค่าความแม่นยำของการชนกันของชิ้นส่วนที่ถูกยึดเล็กๆ ให้เป็น Box
    • สำหรับชิ้นส่วนเมซที่มีความซับซ้อน ใหญ่ อาจต้องสร้างเรขาคณิตการชนกันด้วยวัตถุเล็กลงโดยใช้ความแม่นยำของช่อง

ฮิวมานอยด์

Humanoid เป็นคลาสที่ให้ฟังก์ชันที่หลากหลายแก่ผู้เล่นและตัวละครที่ไม่ใช่ผู้เล่น (NPC) แม้ว่าจะมีพลัง แต่ Humanoid มักมีค่าใช้จ่ายในการคำนวณที่สูง

ปัญหาทั่วไป

  • ปล่อย HumanoidStateTypes ทั้งหมดที่เปิดใช้งานใน NPC - มีค่าใช้จ่ายด้านประสิทธิภาพสำหรับการเปิดใช้งาน HumanoidStateTypes บางประเภท ใหญ่ ปิดที่ไม่จำเป็นต้องใช้สำหรับ NPC ของคุณ ตัวอย่างเช่น นอกจาก NPC ของคุณจะไปปีนบันได ปลอดภัยที่จะปิดสถานะ Climbing
  • การสร้าง, แก้ไข, และสร้างโมเดลด้วย Humanoids หรือ MeshParts เป็นจำนวนมาก - วิธีนี้อาจใช้พลังการประมวลผลจากเอนจิ้นมากเกินไป โดยเฉพาะถ้าโมเดลเหล่านี้ใช้ เสื้อผ้าแบบชั้น สิ่งนี้ยังอาจเป็นปัญหาในเกมที่อวาตาร์กลับคืนมาโดยบ่อยๆ - ใน MicroProfiler แท็ก updateInvalidatedFastClusters ที่ใช้เวลานาน (มากกว่า 4 มิลลิวินาที) มักจะเป็นสัญญาณว่า การสร้างหรือแก้ไขของอวาตาร์จะซ้ำซ้อนมากเกินไป
  • ใช้งาน Humanoids ในกรณีที่ไม่จำเป็น - NPC ที่ไม่มีการเคลื่อนไหวมักจะไม่ต้องการ Humanoid
  • การเล่นอนิเมชันบน NPC จำนวนมากจากเซิร์ฟเวอร์ - อนิเมชัน NPC ที่ทำงานบนเซิร์ฟเวอร์จำเป็นต้องได้รับการจำลองที่เซิร์ฟเวอร์และทำซ้ำไปยังลูกค้า ซึ่งอาจเป็นภาระที่ไม่จำเป็น
  • การเปลี่ยนขนาดและสเกลที่ไม่จำเป็น - การเปลี่ยนขนาด/สเกลทำให้ FastCluster ต้องสร้างใหม่ ลองลดสิ่งนี้ระหว่างการเล่นเกมหากคุณเห็นปัญหาประสิทธิภาพที่เกี่ยวข้องกับ FastCluster นอกจากนี้ การเปลี่ยนแปลงคุณสมบัติอื่น ๆ ก็อาจทำให้ FastCluster ต้องสร้างใหม่ได้ ดังนั้นโดยทั่วไปให้ลดการเปลี่ยนแปลงเหล่านี้ให้มากที่สุด

การบรรเทา

  • เล่นอนิเมชัน NPC บนลูกค้า - ในเกมที่มี NPC จำนวนมาก ให้สร้างAnimator ที่ลูกค้าและเรียกใช้งานอนิเมชันในท้องถิ่น เพื่อลดภาระบนเซิร์ฟเวอร์และความต้องการในการทำสำเนาที่ไม่จำเป็น มันยังอนุญาตให้มีการปรับปรุงเพิ่มเติม (เช่น การเล่นอนิเมชันเฉพาะ NPC ที่อยู่ใกล้ตัวละคร)
  • ใช้ทางเลือกที่เป็นมิตรต่อประสิทธิภาพแทน Humanoids - โมเดล NPC ไม่จำเป็นต้องมีวัตถุฮิวมานอยด์
    • สำหรับ NPC ที่อยู่กับที่ ใช้ AnimationController ที่ง่าย เพราะพวกเขาไม่ต้องเคลื่อนที่ไปมาเพียงแค่เล่นอนิเมชัน
    • สำหรับ NPC ที่เคลื่อนที่ให้พิจารณาการทำคอนโทรลเลอร์การเคลื่อนไหวของคุณเองและใช้ AnimationController สำหรับการเล่นอนิเมชัน ขึ้นอยู่กับความซับซ้อนของ NPC ของคุณ
  • ปิดสถานะฮิวมานอยด์ที่ไม่ได้ใช้งาน - ใช้ Humanoid:SetStateEnabled() เพื่อเปิดใช้งานเฉพาะสถานะที่จำเป็นสำหรับฮิวมานอยด์แต่ละตัว
  • การป้องกันโมเดล NPC ที่เกิดขึ้นบ่อย - แทนที่จะทำลาย NPC อย่างสมบูรณ์ ให้ส่ง NPC ไปยังสระของ NPC ที่ไม่ทำงาน ด้วยวิธีนี้เมื่อจำเป็นต้องมี NPC ใหม่ในการเกิดใหม่ คุณสามารถเปิดใช้งาน NPC ที่มีอยู่จากสระแทน วิธีการนี้เรียกว่า pooling ซึ่งช่วยลดจำนวนครั้งที่จำเป็นต้องสร้างตัวละคร
  • เพียงแค่เกิด NPC เมื่อผู้ใช้ใกล้เข้ามา - อย่าสร้าง NPC เมื่อผู้ใช้ไม่ได้อยู่ในขอบเขต และให้ยกเลิก NPC เมื่อผู้ใช้ออกไป
  • หลีกเลี่ยงการทำการเปลี่ยนแปลงต่อโครงสร้าง Aavatar หลังจากถูกสร้าง - การดัดแปลงบางอย่างต่อโครงสร้าง Aavatar มีผลกระทบต่อประสิทธิภาพที่สำคัญ โดยมีการปรับปรุงบางอย่างที่มีอยู่:
    • สำหรับอนิเมชันทั่วไปที่กำหนดเอง อย่าอัปเดตสถานที่ JointInstance.C0 และ JointInstance.C1 แทนให้ปรับปรุงที่ Motor6D.Transform
    • หากคุณต้องแนบวัตถุ BasePart ใด ๆ กับอวาตาร์ ให้ทำเช่นนั้นนอกโครงสร้างของ Model ของอวาตาร์

ขอบเขตของ MicroProfiler

ขอบเขตการคำนวณที่เกี่ยวข้อง
stepHumanoidการควบคุมฮิวมานอยด์และฟิสิกส์
stepAnimationอนิเมชันฮิวมานอยด์และอนิเมเตอร์
updateInvalidatedFastClustersที่เกี่ยวข้องกับการสร้างหรือแก้ไขอวาตาร์

การเรนเดอร์

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

การเรียกวาด

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

คุณสามารถดูจำนวนการเรียกวาดที่เกิดขึ้นในปัจจุบันได้จากรายการ Render StatsTiming ใน Studio คุณสามารถดู Render Stats ในลูกค้าโดยการกด ShiftF2

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

ปัญหาอื่น ๆ ที่พบบ่อย

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

    วัตถุอย่าง decals, textures และ particles ไม่สามารถรวมกลุ่มได้ดีและนำเสนอการเรียกวาดที่เพิ่มขึ้น โดยเฉพาะอย่างยิ่งการเปลี่ยนแปลงคุณสมบัติของ ParticleEmitters สามารถส่งผลกระทบต่อประสิทธิภาพอย่างรุนแรง

  • พลาดโอกาสในการสร้างกลุ่ม - โดยทั่วไปแล้ว ฉากจะมีเมซเดียวกันซ้ำหลายครั้ง แต่ละสำเนาของเมซมีรหัสทรัพยากรเมซหรือเท็กซ์เจอร์ที่แตกต่างกัน สิ่งนี้จะทำให้ไม่สามารถสร้างกลุ่มได้และส่งผลให้มีการเรียกวาดที่ไม่จำเป็น

    สาเหตุทั่วไปของปัญหานี้คือการนำเข้าฉากทั้งหมดในครั้งเดียว แทนที่จะเป็นการนำเข้าสินค้าแต่ละรายการเข้าสู่ Roblox และจากนั้นซ้ำหลังการนำเข้าเพื่อประกอบฉาก

    แม้จะมีสคริปต์ง่ายๆ เช่นนี้ก็สามารถช่วยคุณระบุชิ้นส่วนเมซที่มีชื่อเดียวกันที่ใช้รหัสเมซแตกต่างกัน:

    for _,descendant in workspace:GetDescendants() do
    if descendant:IsA("MeshPart") then
    print(descendant.Name .. ", " .. descendant.MeshId)
    end
    end

    ผลลัพธ์ (เมื่อเปิดใช้งาน Stack Lines) อาจดูเหมือนอย่างนี้ บรรทัดที่ซ้ำกันแสดงถึงการใช้เมซเดียวกันซึ่งถือว่ายอดเยี่ยม บรรทัดที่ไม่ซ้ำกันไม่ได้แปลว่าจะแย่ แต่นั่นอาจบ่งบอกถึงการมีเมซที่ซ้ำกันในเกมของคุณ ขึ้นอยู่กับการตั้งชื่อของคุณ:

    LargeRock, rbxassetid://106420009602747 (x144) -- ดี
    LargeRock, rbxassetid://120109824668127
    LargeRock, rbxassetid://134460273008628
    LargeRock, rbxassetid://139288987285823
    LargeRock, rbxassetid://71302144984955
    LargeRock, rbxassetid://90621205713698
    LargeRock, rbxassetid://113160939160788
    LargeRock, rbxassetid://135944592365226 -- เป็นระเบิดทั้งหมด
  • ความซับซ้อนของวัตถุสูงเกินไป - แม้ว่าจะไม่สำคัญเท่ากับจำนวนการเรียกวาด แต่จำนวนสามเหลี่ยมในฉากจะมีอิทธิพลต่อความยาวที่ต้องใช้เพื่อเรนเดอร์เฟรม ฉากที่มีจำนวนเมซที่ซับซ้อนมากมายและซับซ้อนเป็นปัญหาทั่วไป และยังรวมถึงฉากที่มีคุณสมบัติ MeshPart.RenderFidelity ที่ตั้งไว้ที่ Precise สำหรับเมซมากเกินไป

  • การสร้างเงามากเกินไป - การจัดการเงาเป็นกระบวนการที่มีค่าใช้จ่ายสูง และแผนที่ที่มีวัตถุแสงที่สร้างเงาจำนวนมากและมีความหนาแน่นสูง (หรือมีส่วนเล็ก ๆ ที่มากเกินไปซึ่งได้รับผลกระทบจากเงา) สามารถประสบปัญหาประสิทธิภาพ

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

  • การเคลื่อนไหวของ MeshPart ที่มีการสกินมากเกินไป - MeshParts ที่ใช้เป็นส่วนหนึ่งของโมเดล โดยไม่มี Humanoid จะถูกจัดกลุ่มโดยใช้ FastCluster ที่มีการจัดกลุ่มเชิงพื้นที่ เมื่อตราสารเหล่านี้เคลื่อนที่ จะต้องถูกเพิ่มและลบออกตลอดเวลา จากนั้นกลุ่มจะต้องสร้างใหม่ซึ่งส่งผลต่อประสิทธิภาพ

    • วิธีที่มีประสิทธิภาพในการดำเนินการคือการฝัง Humanoid ไว้ในโมเดล การมีอยู่ของ Humanoid จะปฏิเสธพฤติกรรมการจัดกลุ่มเชิงพื้นที่เริ่มต้น โดยบังคับให้ใช้ FastCluster เดียวที่เป็นเอกภาพสำหรับโมเดลทั้งหมด ดังนั้นการอัปเดตตำแหน่งจะไม่จำเป็นต้องสร้างกลุ่มใหม่อีกต่อไป ช่วยบรรเทาคอขวดทางด้านประสิทธิภาพ เทคนิคนี้ควรสงวนไว้เฉพาะสำหรับ MeshParts ที่คาดว่าจะเคลื่อนไหว เนื่องจากอาจนำไปสู่เป็นภาระของหน่วยความจำและทำให้ข้อดีของการเพิ่มประสิทธิภาพเชิงพื้นที่ลดลง แนะนำให้คุณจะต้องทดสอบประสิทธิภาพของเกมของคุณหลังจากที่คุณทำการเปลี่ยนแปลงเหล่านี้ โปรดดู เคล็ดลับประสิทธิภาพฮิวมานอยด์ สำหรับข้อมูลเพิ่มเติม
  • ชิ้นส่วนใน Model มากเกินไป - ชิ้นส่วนในโมเดลมากเกินไปอาจทำให้การสร้างใหม่เกิดขึ้นบ่อยขึ้นโดยเฉพาะอย่างยิ่งเนื่องจากความเป็นไปได้ที่คุณสมบัติของชิ้นส่วนจะเปลี่ยน ทำให้ต้องการการสร้างใหม่แบบเต็มรูปแบบ ค้นหาความสมดุลที่เหมาะสมของชิ้นส่วนในโมเดลเมื่อใช้ FastCluster

การบรรเทา

  • การสร้างกลุ่มเมซเดียวกันและลดจำนวนเมซเฉพาะ - หากแน่ใจว่าเมซที่เหมือนกันทั้งหมดมีรหัสทรัพยากรที่อยู่เบื้องหลังเหมือนกัน เอนจิ้นสามารถรับรู้และเรนเดอร์ในแบบการเรียกวาดเดียว ตรวจสอบให้แน่ใจว่าได้อัปโหลดเมซแต่ละเมซในแผนที่เพียงครั้งเดียวและจากนั้นซ้ำใน Studio เพื่อใช้ซ้ำ แทนที่จะนำเข้าฉากที่มีขนาดใหญ่ทั้งหมดซึ่งอาจทำให้เมซที่เหมือนกันมีรหัสเนื้อหาที่แยกออกจากกันและถูกนำไปถือเป็นสินทรัพย์เฉพาะโดยเอนจิ้น แพ็คเกจ เป็นกลไกที่ช่วยในเรื่องการใช้ซ้ำวัตถุ
  • การตัดกลุ่ม - การตัดกลุ่มหมายถึงกระบวนการกำจัดการเรียกวาดสำหรับวัตถุที่ไม่เกี่ยวข้องกับเฟรมที่เรนเดอร์ในที่สุด โดยค่าเริ่มต้น เอนจิ้นจะข้ามการเรียกวาดสำหรับวัตถุที่อยู่นอกมุมมองของกล้อง (frustum culling) และชิ้นส่วน, เมซ, และภูมิประเทศที่ไม่สามารถมองเห็นได้จากวัตถุอื่น ๆ (occlusion culling) ในบางสถานการณ์ เช่น สภาพแวดล้อมในบ้าน คุณอาจมีความสามารถในการ implement ระบบห้องหรือพอร์ทัลและทำการตัดกลุ่มวัตถุอย่างมือต่อการลดการเรียกวาดหรือโหลดคอมพิวเตอร์โดยรวม
  • ลดระดับรายละเอียดของโมเดล - เปิดใช้งาน instance streaming และตั้งค่า LevelOfDetail ของโมเดลให้เป็น SLIM เพื่อเรนเดอร์ โมเดล SLIM ที่เบาและปรับแต่ง เมื่อระยะห่างจากกล้องเพิ่มขึ้น
  • ลดระดับรายละเอียดของอวาตาร์ - เปิดใช้งาน instance streaming และตั้ง Workspace.EnableSLIMAvatars เพื่อเรนเดอร์อวาตาร์ทั่วๆ ไปในฐานะ ตัวแทน SLIM ที่เบาและปรับแต่ง โดยมีการสนับสนุนอนิเมชันอย่างเต็มที่เมื่อระยะห่างจากกล้องเพิ่มขึ้น
  • ลดความแม่นยำของเรนเดอร์ - ตั้งค่า MeshPart.RenderFidelity เป็น Automatic หรือ Performance วิธีนี้จะช่วยให้เมซย้อนกลับไปยังทางเลือกที่มีความซับซ้อนน้อยลง ซึ่งสามารถลดจำนวนโพลิกอนที่จำเป็นต้องถูกวาด
  • ปิดการสร้างเงาบนส่วนต่าง ๆ และวัตถุแสงที่เหมาะสม - เอนจิ้น Roblox จะลดคุณภาพเงาโดยอัตโนมัติตามขอบเขตของคุณภาพกราฟิกของลูกค้า ลดลงจนในระดับคุณภาพต่ำกว่า 4 จะไม่มีการสร้างเงาอีกต่อไป อย่างไรก็ตาม คุณสามารถปิดใช้คุณสมบัติปิดการสร้างเงาบนวัตถุต่าง ๆ และแสงเพื่อปรับปรุงประสิทธิภาพในขณะที่เงาถูกเปิดใช้งาน และเพิ่มโอกาสในการให้เงายังคงเปิดอยู่ ปรับแต่งต่าง ๆ ที่คุณสามารถทำได้ทั้งขณะเวลาเริ่มต้นหรือที่ดำเนินการซ้ำ:
    • ใช้คุณสมบัติ BasePart.CastShadow เพื่อปิดการสร้างเงาบนชิ้นส่วนเล็กๆ ที่เงาไม่น่าจะมองเห็นได้ กลยุทธ์นี้มีผลดีอย่างมากเมื่อใช้กับชิ้นส่วนที่ห่างไกลจากกล้องของผู้ใช้

    • ปิดเงาสำหรับวัตถุที่เคลื่อนไหวเมื่อเป็นไปได้

    • ปิด Light.Shadows ในอินสแตนซ์แสงที่วัตถุไม่ต้องการแสดงเงา

    • จำกัดระยะและมุมของอินสแตนซ์แสง

    • ใช้อินสแตนซ์แสงที่น้อยลง

    • พิจารณาที่จะปิดแสงที่อยู่นอกช่วงที่กำหนดหรือในแต่ละห้องสำหรับสภาพแวดล้อมในร่ม

ขอบเขตของ MicroProfiler

ขอบเขตการคำนวณที่เกี่ยวข้อง
Prepare and Performการเรนเดอร์โดยรวม
Perform/Scene/computeLightingPerformการอัปเดตตารางแสงและเงา
LightGridCPUการอัปเดตตารางแสงพิกเซล
ShadowMapSystemการสร้างแผนที่เงา
Perform/Scene/UpdateViewการเตรียมการเรนเดอร์และการอัปเดตอนิเมชัน
Perform/Scene/RenderViewการเรนเดอร์และการประมวลผลหลัง

เครือข่ายและการทำสำเนา

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

ปัญหาทั่วไป

  • การเคลื่อนไหวที่มากเกินไปทางไกล - การส่งข้อมูลจำนวนมากผ่าน RemoteEvent หรือ RemoteFunction หรือการเรียกใช้อย่างบ่อยอาจทำให้ใช้เวลา CPU สูงขึ้นในการประมวลผลแพ็กเกจที่เข้ามาในทุกเฟรม ข้อผิดพลาดทั่วไป รวมถึง:

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

    ที่มักจะเป็นสาเหตุของปัญหานี้คือข้อมูลอนิเมชันที่ซับซ้อนที่บันทึกโดย Animation Editor ปลั๊กอินใน rigs หากข้อมูลเหล่านี้ไม่ถูกลบออกก่อนที่เกมจะถูกเผยแพร่และโมเดลที่อนิเมทถูกโคลนเป็นประจำ ข้อมูลจำนวนมากจะถูกทำซ้ำอย่างไม่จำเป็น

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

การบรรเทา

คุณสามารถใช้กลยุทธ์ต่อไปนี้เพื่อลดการทำสำเนาอย่างไม่จำเป็น:

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

ขอบเขตของ MicroProfiler

ขอบเขตการคำนวณที่เกี่ยวข้อง
ProcessPacketsการประมวลผลแพ็กเกจเครือข่ายที่เข้ามา เช่น การเรียกเหตุการณ์และการเปลี่ยนแปลงคุณสมบัติ
Allocate Bandwidth and Run Sendersเหตุกลางออกของเซิร์ฟเวอร์

การใช้หน่วยความจำของทรัพยากร

กลไกที่มีผลกระทบสูงสุดที่ผู้สร้างสามารถใช้เพื่อปรับปรุงการใช้หน่วยความจำของลูกค้า คือการเปิดใช้งาน instance streaming

การทำงานของ instance streaming

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

หากคุณพบปัญหาเรื่องหน่วยความจำและได้ปิดการใช้งาน instance streaming พิจารณาปรับปรุงเกมของคุณเพื่อรองรับมัน โดยเฉพาะอย่างยิ่งถ้าโลก 3D ของคุณมีขนาดใหญ่ Instance streaming อิงตามระยะทางในพื้นที่ 3D ดังนั้นโลกที่มีขนาดใหญ่จึงได้รับประโยชน์จากมันมากขึ้น

หาก instance streaming เปิดใช้งาน คุณสามารถเพิ่มความเข้มข้นของการทำงานนี้ได้ ตัวอย่างเช่น พิจารณา:

  • ลดการใช้ Enum.ModelStreamingMode.Persistent ที่เป็นไปได้ คุณอาจจำเป็นต้องปรับปรุงฟังก์ชันถ้าใช้เป็นมาตรการสำหรับการใช้งานร่วมกัน
  • ลด Workspace.StreamingMinRadius และ Workspace.StreamingTargetRadius

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

ปัญหาอื่น ๆ ที่พบบ่อย

  • การทำสำเนาทรัพยากร - ข้อผิดพลาดทั่วไปคือการอัปโหลดทรัพยากรเดียวกันหลายครั้งทำให้มีรหัสทรัพยากรที่แตกต่างกัน สิ่งนี้อาจทำให้เนื้อเดียวกันถูกโหลดเข้าไปในหน่วยความจำหลายครั้ง

  • ปริมาณทรัพยากรเกินไป - แม้ว่าทรัพยากรจะไม่เหมือนกัน แต่ก็มีกรณีที่คุณพลาดโอกาสในการใช้ทรัพยากรเดียวกันและประหยัดหน่วยความจำ

  • ไฟล์เสียง - ไฟล์เสียงอาจเป็นปัจจัยที่คาดไม่ถึงในการใช้หน่วยความจำโดยเฉพาะหากคุณโหลดทั้งหมดในลูกค้าในครั้งเดียวมากกว่าที่จะโหลดเฉพาะสิ่งที่คุณต้องการสำหรับช่วงเกม ในยุทธศาสตร์ โปรดดูที่ เวลาโหลด

  • เท็กซ์เจอร์ความละเอียดสูง - การใช้หน่วยความจำกราฟิกสำหรับเท็กซ์เจอร์ไม่เกี่ยวข้องกับขนาดของเท็กซ์เจอร์บนดิสก์; จำนวนพิกเซลในเท็กซ์เจอร์จะกำหนดการใช้หน่วยความจำ ตัวอย่างเช่น เท็กซ์เจอร์ขนาด 1024x1024 พิกเซลจะใช้หน่วยความจำกราฟิกมากกว่าสี่เท่าของเท็กซ์เจอร์ขนาด 512x512

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

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

การบรรเทา

  • อัปโหลดทรัพยากรเพียงครั้งเดียว - ใช้รหัสทรัพยากรเดียวกันซ้ำในวัตถุและตรวจสอบให้แน่ใจว่าทรัพยากรเดียวกัน โดยเฉพาะเมซและภาพ จะไม่ได้อัปโหลดแยกกันหลายครั้ง

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

    • แม้จะไม่มี API ที่ตรวจจับความคล้ายคลึงกันของทรัพยากรโดยอัตโนมัติ แต่คุณสามารถเก็บรวบรวมรหัสทรัพยากรภาพทั้งหมดในสถานที่ของคุณ (ทั้งแบบแมนนวลหรือด้วยสคริปต์), ดาวน์โหลดพวกเขา, และเปรียบเทียบโดยใช้เครื่องมือการเปรียบเทียบภายนอก
    • สำหรับชิ้นส่วนเมซ กลยุทธ์ที่ดีที่สุดคือการนำรหัสเมซที่ไม่ซ้ำกันและจัดระเบียบตามขนาดเพื่อระบุการซ้ำที่ไม่ต้องการ
    • แทนที่จะใช้เท็กซ์เจอร์ที่แยกกันสำหรับสีที่ต่างกัน ให้อัปโหลดเท็กซ์เจอร์เดียวและใช้คุณสมบัติ SurfaceAppearance.Color เพื่อใช้ลูกเล่นต่าง ๆ
  • นำเข้าทรัพยากรในแผนที่แยกกัน - แทนที่จะนำเข้าแผนที่ทั้งหมดในครั้งเดียว ให้ทำการนำเข้าสินค้าและประกอบในแผนที่โดยแยกกัน เครื่องมือการนำเข้าไม่ได้ทำการลบข้อมูลซ้ำหากมีการใช้งานเมซจำนวนมากและหากการนำเข้าแผนที่ขนาดใหญ่โดยมีแผ่นพื้นไม่มีที่สิ้นสุดหลายแผ่น เมซแต่ละชิ้นจะถูกนำเข้าเป็นทรัพยากรแยกจากกัน (แม้ว่าจะอยู่ในรูปที่ซ้ำกัน) สิ่งนี้อาจทำให้เกิดปัญหาเรื่องประสิทธิภาพและหน่วยความจำในอนาคต เนื่องจากทุกๆ เมซจะถูกนำมาปฏิบัติอย่างอิสระและใช้หน่วยความจำและการเรียกวาดไปด้วย

  • จำกัดพิกเซลของภาพ ให้อยู่ในจำนวนที่จำเป็น ไม่เกินกว่านั้น หากไม่ได้อัปโหลดภาพซึ่งใช้พื้นที่มากทางกายภาพบนหน้าจอ โดยทั่วไปใช้เพียงไม่เกิน 512x512 พิกเซล รูปภาพเล็กๆ ส่วนใหญ่ควรมีขนาดเล็กกว่าหรือเท่ากับ 256x256 พิกเซล

  • ใช้แผ่นตัด เพื่อที่จะให้การใช้หน่วยความจำสูงสุดมีการใช้เท็กซ์เจอร์ใหม่ในแผนที่ 3D สำหรับขั้นตอนและตัวอย่างเกี่ยวกับการสร้างแผ่นตัด โปรดดูที่ สร้างแผ่นตัด

    นอกจากนี้ คุณยังสามารถพิจารณาใช้สไปรท์ชีทเพื่อโหลดภาพ UI ขนาดเล็กหลายภาพในรูปภาพเดียว จากนั้นคุณสามารถใช้ ImageLabel.ImageRectOffset และ ImageLabel.ImageRectSize เพื่อแสดงชิ้นส่วนของแผ่น

เวลาโหลด

เกมจำนวนมากจะใช้หน้าจอโหลดที่กำหนดเองและใช้เมธอด ContentProvider:PreloadAsync() เพื่อขอทรัพยากร เพื่อให้ภาพ, เสียง, และเมซถูกดาวน์โหลดในพื้นหลัง

ข้อดีของวิธีการนี้คือช่วยให้คุณมั่นใจว่าชิ้นส่วนสำคัญของเกมโหลดได้อย่างเต็มที่โดยไม่มีการข้าม อย่างไรก็ตาม ข้อผิดพลาดทั่วไปคือการใช้วิธีการนี้มากเกินไปเพื่อโหลดทรัพยากรมากกว่าที่ต้องการจริง ๆ

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

อีกหนึ่งแนวปฏิบัติที่คล้ายกันคือการใช้ ContentProvider.RequestQueueSize เพื่อให้แน่ใจว่าทรัพยากรที่ร้องขอทั้งหมดเสร็จสิ้นการโหลด อย่างไรก็ตาม วิธีนี้มีปัญหาเดียวกัน นั่นคือเวลาการโหลดสูงขึ้นอย่างมาก ขณะเดียวกันก็เป็นวิธีการที่ไม่น่าเชื่อถือเนื่องจากลักษณะที่เปลี่ยนแปลงของมัน

แทนที่จะทำเช่นนั้นให้ใช้ ContentProvider:PreloadAsync() ในกรณีที่จำเป็น ซึ่งรวมถึง:

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

หากคุณต้องโหลดทรัพยากรจำนวนมาก เราแนะนำให้คุณจัดให้มีปุ่ม ข้ามการโหลด

©2026 Roblox Corporation. Roblox, โลโก้ Roblox และ Powering Imagination เป็นส่วนหนึ่งของเครื่องหมายการค้าที่จดทะเบียน และไม่ได้จดทะเบียนของเราในสหรัฐฯ และประเทศอื่นๆ