การรับตัวแปรจากสคริปต์อื่นใน Unity นั้นค่อนข้างตรงไปตรงมา
ที่จริงแล้ว แม้ว่าคุณจะเพิ่งเริ่มต้นใช้งานพื้นฐานของ Unity คุณก็มีโอกาสสร้างการอ้างอิงสาธารณะระหว่างตัวแปรสคริปต์กับอ็อบเจ็กต์อื่นแล้ว โดยการลากและวางลงใน Inspector
คุณอาจเข้าถึงส่วนประกอบบนวัตถุเกมจากโค้ดแล้ว หรือสร้างการเชื่อมต่อระหว่างวัตถุผ่านการโต้ตอบระหว่างวัตถุเหล่านั้น เช่น เมื่อวัตถุสองชิ้นชนกัน
แต่ถ้าคุณต้องการสร้างการเชื่อมต่อระหว่างสคริปต์หรือส่วนประกอบต่างๆ บนอ็อบเจ็กต์ที่แตกต่างกันซึ่งไม่ได้โต้ตอบกันล่ะ
คุณจะติดตามตัวแปรทั่วโลกทั้งเกม เช่น คะแนนหรือสุขภาพของผู้เล่นได้อย่างไร
และอะไรคือวิธีที่ดีที่สุดในการทำเช่นนั้นโดยไม่ทำให้โครงการของคุณยุ่งเหยิง?
ในบทความนี้ คุณจะได้เรียนรู้วิธีการพื้นฐานในการเข้าถึงตัวแปรบนสคริปต์อื่น พร้อมด้วยเคล็ดลับแนวทางปฏิบัติที่ดีที่สุดเพื่อช่วยให้โปรเจ็กต์ของคุณสะอาดและจัดการได้ง่าย
สิ่งที่คุณจะพบในหน้านี้:
- วิธีเข้าถึงตัวแปรจากสคริปต์อื่นใน Unity
- วิธีเข้าถึงตัวแปรด้วยตนเองโดยใช้ Inspector
- วิธีใช้ Get Component ใน Unity
- วิธีค้นหาวัตถุต่าง ๆ ในฉาก
- ตัวแปรโกลบอลใน Unity
- ตัวแปรคงที่ใน Unity
- วิธีใช้สถิติเพื่อสร้างผู้จัดการเกม Singleton
- ตัวแปรวัตถุที่สามารถเขียนสคริปต์ได้ใน Unity
- วิธีสร้างตัวแปร Scriptable Object
- ตัวแปรโกลบอลของ Scriptable Object เทียบกับตัวแปรคงที่
มาเริ่มกันเลย…
วิดีโอภาพรวม
สำหรับภาพรวมทั่วไปของวิธีรับตัวแปรจากสคริปต์อื่น ให้ลองใช้ของฉันวิดีโอหรือติดตามบทความเต็มด้านล่าง
วิธีเข้าถึงตัวแปรจากสคริปต์อื่นใน Unity
ในการเข้าถึงตัวแปรจากสคริปต์อื่น คุณจะต้องได้รับการอ้างอิงถึงประเภทของออบเจ็กต์ คลาส หรือส่วนประกอบใดก็ตามที่คุณพยายามเข้าถึง
ตัวอย่างเช่น สมมติว่าฉันกำลังเขียนสคริปต์สุขภาพของผู้เล่นสำหรับตัวละคร 2D Knight ด้านล่าง และฉันต้องการเล่นเอฟเฟกต์เสียงทุกครั้งที่ผู้เล่นได้รับบาดเจ็บ
ฉันมีแหล่งกำเนิดเสียงในตัวละครและมีฟังก์ชัน Player Hurt ในสคริปต์ที่ฉันสามารถใช้เพื่อกระตุ้นเสียงได้ แล้วฉันจะเชื่อมต่อทั้งสองอย่างได้อย่างไร
ในตัวอย่างนี้ ฉันต้องการข้อมูลอ้างอิงถึงส่วนประกอบแหล่งกำเนิดเสียงของตัวละคร Knight ของฉัน
ก่อนที่ฉันจะสามารถทริกเกอร์ส่วนประกอบแหล่งกำเนิดเสียงให้เล่นจากสคริปต์ก่อนอื่น ฉันต้องได้รับข้อมูลอ้างอิงก่อน
ในสคริปต์สุขภาพผู้เล่นของฉัน ฉันได้สร้างสาธารณะแล้วแหล่งกำเนิดเสียงตัวแปรอ้างอิง
แบบนี้:
PlayerHealth ระดับสาธารณะ: MonoBehavior { ผู้เล่น AudioSource สาธารณะ AudioSource; }
ต่อไป ฉันต้องเชื่อมต่อการอ้างอิงนั้นกับส่วนประกอบแหล่งกำเนิดเสียงบนตัวละคร เพื่อให้สคริปต์รู้ว่าแหล่งเสียงใดที่ฉันอ้างถึง
มีหลายวิธีที่ฉันสามารถทำได้ แต่มาเริ่มด้วยวิธีที่ง่ายที่สุดกันดีกว่า
วิธีเข้าถึงตัวแปรด้วยตนเองโดยใช้ Inspector
ในตัวอย่างนี้ฉันได้เพิ่มไฟล์แหล่งกำเนิดเสียงให้กับออบเจ็กต์เครื่องเล่นและได้สร้างตัวแปรอ้างอิงแหล่งเสียงสาธารณะในสคริปต์ความสมบูรณ์ของเครื่องเล่นของฉัน
ฉันทำให้ตัวแปรแหล่งเสียงเป็นแบบสาธารณะ ซึ่งหมายความว่าตัวแปรดังกล่าวจะมองเห็นได้ในตัวตรวจสอบและพร้อมใช้งานสำหรับสคริปต์อื่น
ตัวแปรสาธารณะและส่วนตัวใน Unity
หากภาครัฐและเอกชนตัวแก้ไขการเข้าถึงเป็นตัวแปรใหม่สำหรับคุณ กล่าวง่ายๆ ก็คือ ตัวแปรสาธารณะสามารถเข้าถึงได้โดยสคริปต์อื่นและมองเห็นได้ใน Inspector ในขณะที่ตัวแปรส่วนตัวไม่สามารถเข้าถึงได้โดยสคริปต์อื่น และจะไม่แสดงใน Inspector
ตัวแก้ไขการเข้าถึงจะถูกเพิ่มก่อนชนิดข้อมูล และหากไม่มีการใช้ทั้งสองอย่าง ตัวแปรจะเป็นส่วนตัวตามค่าเริ่มต้น...
นี่คือสิ่งที่ดูเหมือนในโค้ด:
ลอยสาธารณะ publicFloat; สตริงส่วนตัว privateFloat; int ส่วนตัวจำนวนเต็ม;
คุณอาจใช้ทั้งตัวแปรสาธารณะและตัวแปรส่วนตัวในบทช่วยสอนและตัวอย่างอื่นๆ แล้ว และโดยทั่วไป นี่เป็นวิธีที่ง่ายที่สุดในการแสดงตัวแปรในตัวตรวจสอบหรืออนุญาตให้สคริปต์อื่นเข้าถึงได้
อย่างไรก็ตาม… ยังมีอะไรมากกว่านั้นอีกเล็กน้อย
สามารถแสดงตัวแปรส่วนตัวในตัวตรวจสอบได้โดยใช้ฟิลด์การทำให้เป็นอนุกรม,
แบบนี้:
// สิ่งนี้จะแสดงในตัวตรวจสอบ [SerializeField]private float playerHealth;
คุณยังสามารถทำให้ตัวแปรพร้อมใช้งานสำหรับสคริปต์อื่นโดยไม่ต้องแสดงในตัวตรวจสอบด้วย
แบบนี้:
// สิ่งนี้จะไม่แสดงใน inspector[HideInInspector] public float playerHealth;
โดยทั่วไปแล้ว แนวทางปฏิบัติที่ดีคือทำให้ตัวแปรเป็นแบบสาธารณะเฉพาะในกรณีที่สคริปต์อื่นจำเป็นต้องเข้าถึงตัวแปรนั้น และหากไม่เป็นเช่นนั้น ก็ควรเก็บไว้เป็นส่วนตัว
อย่างไรก็ตาม หากสคริปต์อื่นไม่จำเป็นต้องเข้าถึง แต่คุณต้องการดูในตัวตรวจสอบ คุณสามารถใช้ Serialize Field แทนได้
สิ่งนี้จะทำให้ตัวแปรเป็นส่วนตัวแต่ทำให้มองเห็นได้ในตัวตรวจสอบ
อย่างไรก็ตาม... เพื่อรักษาตัวอย่างให้เรียบง่าย ในบทช่วยสอนและตัวอย่างจำนวนมาก คุณมักจะเห็นตัวแปรถูกทำเครื่องหมายเป็นสาธารณะเพื่อจุดประสงค์ในการแก้ไขในตัวตรวจสอบ
ในตัวอย่างของฉัน ฉันใช้ตัวแปรสาธารณะเพราะฉันต้องการเข้าถึงตัวแปรนั้นจากสคริปต์อื่นและเพื่อที่ฉันจะได้ตั้งค่าตัวแปรใน Inspector ซึ่งเป็นสิ่งที่ฉันจะทำต่อไป
ตั้งค่าตัวแปรในตัวตรวจสอบ
ทั้งสคริปต์และแหล่งที่มาของเสียงจะแนบไปกับออบเจ็กต์เกมเดียวกัน ซึ่งในกรณีนี้คือเครื่องเล่น และการเชื่อมต่อทั้งสองอย่างทำได้ง่ายเพียงแค่ลากส่วนประกอบของแหล่งกำเนิดเสียงไปยังช่องแหล่งกำเนิดเสียงของเครื่องเล่นในส่วนประกอบของสคริปต์
แบบนี้:
คลิกและลากส่วนประกอบไปยังช่องว่างเพื่อสร้างข้อมูลอ้างอิง
ฉันยังสามารถใช้เครื่องมือเลือกวงกลม ซึ่งจะแสดงรายการวัตถุเกมทั้งหมดในฉากพร้อมส่วนประกอบที่ตรงกับประเภทการอ้างอิง ในกรณีนี้คือวัตถุเกมใด ๆ ที่มีแหล่งกำเนิดเสียงแนบอยู่
แบบนี้:
การใช้การเลือกวงกลมจะแสดงรายการวัตถุทั้งหมดในฉากพร้อมส่วนประกอบที่ตรงกับประเภทการอ้างอิง
ตอนนี้ฉันมีการอ้างอิงแคชไปยังส่วนประกอบแหล่งกำเนิดเสียงแล้ว ฉันจึงสามารถเข้าถึงคุณสมบัติและวิธีการสาธารณะทั้งหมดของมันได้
แบบนี้:
PlayerHealth ระดับสาธารณะ: MonoBehaviour { ผู้เล่น AudioSource สาธารณะ AudioSource; เป็นโมฆะ PlayerHurt () { // สร้างความเสียหาย! ผู้เล่น AudioSource.Play (); }}
ฉันสามารถใช้วิธีเดียวกันนี้เพื่อเข้าถึงอินสแตนซ์ของสคริปต์ได้เช่นกัน
เช่นเดียวกับเมื่อสร้างตัวแปรอ้างอิงแหล่งที่มาของเสียง ตัวแปรอ้างอิงสคริปต์จะทำงานในลักษณะเดียวกัน
แทน“แหล่งเสียง”อย่างไรก็ตาม เพียงพิมพ์ชื่อของคลาสเป็นประเภทของตัวแปร
ตัวอย่างเช่น ฉันสามารถสร้างการอ้างอิงถึงอินสแตนซ์ของ“สุขภาพของผู้เล่น”สคริปต์ที่ฉันเพิ่งเขียน
แบบนี้:
ผู้เล่นสาธารณะสุขภาพผู้เล่นสุขภาพ;
เช่นเดียวกับส่วนประกอบแหล่งกำเนิดเสียง ฉันสามารถตั้งค่าตัวแปรนี้ในตัวตรวจสอบเพื่ออ้างอิงอินสแตนซ์ใดๆ ของสคริปต์ความสมบูรณ์ของผู้เล่นในฉาก และใช้การเชื่อมต่อนั้นเพื่อเข้าถึงตัวแปรและวิธีการสาธารณะ
แบบนี้:
คลาสสาธารณะ SomeOtherScript: MonoBehaviour { PlayerHealth สาธารณะ playerHealth; เป็นโมฆะเริ่มต้น () { playerHealth.playerAudioSource.Play (); }}
วิธีการสร้างและกำหนดข้อมูลอ้างอิงด้วยตนเองนี้ทำได้ง่ายและตรงไปตรงมา
และมีโอกาสที่ถ้าคุณเคยทำอะไรเลยใน Unity แสดงว่าคุณได้สร้างข้อมูลอ้างอิงเช่นนี้มาก่อนแล้ว
แต่ถ้าคุณไม่สามารถลากและวางวัตถุในตัวตรวจสอบได้ล่ะ
อาจเป็นเพราะคอมโพเนนต์ถูกสร้างขึ้นขณะรันไทม์หรือยังไม่มีอยู่จริง
หรืออาจเป็นได้ว่าฟิลด์นั้นเป็นแบบส่วนตัวและไม่สามารถมองเห็นได้ในตัวตรวจสอบ
และในขณะที่ยังสามารถทำให้ฟิลด์ส่วนตัวเป็นอนุกรมอาจเป็นไปได้ว่าคุณไม่จำเป็นต้องเปลี่ยนตัวแปรจาก Inspector และต้องการซ่อนมันไว้เพื่อรักษาสคริปต์ให้เรียบง่ายและจัดการได้ง่าย
ไม่ว่าจะด้วยเหตุผลใดก็ตาม คุณจะได้รับการอ้างอิงถึงบางสิ่งโดยไม่ต้องกำหนดด้วยตนเองได้อย่างไร
ทางเลือกหนึ่งคือใช้ Get Component...
วิธีใช้ Get Component ใน Unity
รับส่วนประกอบเป็นวิธีการค้นหาส่วนประกอบชนิดใดชนิดหนึ่งโดยเฉพาะ
ช่วยให้คุณสามารถค้นหาส่วนประกอบประเภทที่ระบุบนวัตถุเกมหนึ่งรายการหรือหลายรายการและรับข้อมูลอ้างอิงได้
สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับการอ้างอิงถึงส่วนประกอบที่อยู่บนออบเจ็กต์เดียวกันกับสคริปต์การเรียก แต่ยังสามารถใช้เพื่อค้นหาส่วนประกอบบนออบเจ็กต์เกมอื่นได้เช่นกัน
แล้วมันทำงานยังไง?
รับ Component ใช้เวลาประเภททั่วไปซึ่งหากคุณดูโค้ดด้านล่างนี้ จะถูกป้อนแทน T ในวงเล็บเหลี่ยม
GetComponent();
หากวงเล็บเหลี่ยม “
ในกรณีนี้ หมายความว่า Get Component สามารถค้นหาส่วนประกอบประเภทใดก็ได้ และคุณจะต้องระบุประเภทในวงเล็บเหลี่ยมเมื่อใช้งาน
เพียงแทนที่ "T" ด้วยส่วนประกอบประเภทใดก็ได้ (หรือชื่อคลาส) ที่คุณต้องการค้นหา
เช่นนี้ หากต้องการค้นหาส่วนประกอบแหล่งเสียง:
GetComponent<แหล่งเสียง>();
ในตัวอย่างก่อนหน้านี้ ฉันสร้างการอ้างอิงสาธารณะไปยังแหล่งที่มาของเสียงของเครื่องเล่นด้วยตนเอง โดยตั้งค่าไว้ใน Inspector
เมื่อใช้ Get Component ฉันสามารถตั้งค่าการอ้างอิงที่ต้องการใน Start โดยไม่ต้องเปิดเผยเป็นตัวแปรสาธารณะ
แบบนี้:
PlayerHealth ระดับสาธารณะ: MonoBehaviour { AudioSource playerAudioSource; เป็นโมฆะเริ่มต้น () { playerAudioSource = GetComponent (); }}
คุณอาจสังเกตเห็นว่าฉันไม่ได้ระบุว่าคอมโพเนนต์แนบไปกับออบเจ็กต์เกมใด ฉันแค่พิมพ์ว่า “GetComponent…”
ใช้งานได้เนื่องจากส่วนประกอบที่ฉันต้องการอยู่บนวัตถุเกมเดียวกันกับสคริปต์
แต่ถ้าไม่ใช่ล่ะ?
จะเกิดอะไรขึ้นถ้ามันอยู่บนออบเจ็กต์ลูก หรือออบเจ็กต์พาเรนต์ หรือที่อื่นทั้งหมดล่ะ?
รับส่วนประกอบจากวัตถุอื่น
หากต้องการรับส่วนประกอบจากวัตถุเกมอื่น คุณจะต้องมีการอ้างอิงถึงวัตถุเกมนั้นก่อน (อ่านเพิ่มเติมเกี่ยวกับวิธีการดำเนินการในภายหลัง)
GameObject อื่น ๆGameObject;
เมื่อคุณมีแล้ว คุณสามารถเรียก Get Component ได้โดยใช้การอ้างอิงของวัตถุเกมและตัวดำเนินการจุด
แบบนี้:
PlayerHealth ระดับสาธารณะ: MonoBehaviour { ผู้เล่น AudioSource สาธารณะ AudioSource; GameObject สาธารณะ otherGameObject; เป็นโมฆะเริ่มต้น () { playerAudioSource = otherGameObject.GetComponent (); }}
เพื่อให้ใช้งานได้ โดยปกติคุณจะต้องมีการอ้างอิงถึงออบเจ็กต์ที่แนบคอมโพเนนต์ ยกเว้นว่าคอมโพเนนต์นั้นอยู่บนออบเจ็กต์ลูกหรือพาเรนต์ของออบเจ็กต์
ในกรณีนี้ก็สามารถใช้งานได้รับส่วนประกอบในเด็กหรือรับส่วนประกอบในพาเรนต์เพื่อรับส่วนประกอบโดยไม่ต้องอ้างอิงถึงวัตถุก่อน
นี่คือวิธีที่คุณทำ
วิธีใช้ Get Component ใน Children
รับส่วนประกอบในเด็กทำงานในลักษณะเดียวกับ Get Component ยกเว้น แทนที่จะตรวจสอบเฉพาะวัตถุเกมที่ระบุ แต่จะตรวจสอบวัตถุลูกด้วย
แบบนี้:
PlayerHealth ระดับสาธารณะ: MonoBehaviour { AudioSource playerAudioSource; เป็นโมฆะเริ่มต้น () { playerAudioSource = GetComponentInChildren (); }}
โปรดทราบว่า Get Component ใน Children จะตรวจสอบวัตถุเกมของตัวเองและลูกๆ ของมันทุกคน
ซึ่งหมายความว่า หากมีองค์ประกอบที่ตรงกันบนออบเจ็กต์เกมที่เรียกใช้มันอยู่แล้ว สิ่งนี้จะถูกส่งคืน ไม่ใช่ส่วนประกอบบนออบเจ็กต์ลูก
วิธีใช้ Get Component ใน Parent
เช่นเดียวกับ Get Component ใน Children คุณยังสามารถรับส่วนประกอบจากอ็อบเจ็กต์พาเรนต์ได้เช่นกัน!
แบบนี้:
การใช้ System.Collections; การใช้ System.Collections.Generic; การใช้ UnityEngine; PlayerHealth ระดับสาธารณะ: MonoBehaviour { ผู้เล่น AudioSource สาธารณะ AudioSource; เป็นโมฆะเริ่มต้น () { playerAudioSource = GetComponentInParent (); }}
เช่นเดียวกับ Get Component ใน Childrenรับส่วนประกอบในพาเรนต์ตรวจสอบทั้งออบเจ็กต์เกมที่ถูกเรียกใช้และพาเรนต์ของออบเจ็กต์
ดังนั้นหากมีส่วนประกอบที่ตรงกันบนออบเจ็กต์เกมอยู่แล้ว ส่วนประกอบนั้นจะถูกส่งกลับเหมือนกับว่าคุณใช้วิธี Get Component มาตรฐาน
นี่อาจเป็นปัญหาเมื่อคุณใช้ส่วนประกอบประเภทเดียวกันหลายรายการ และคุณต้องการแยกความแตกต่างระหว่างส่วนประกอบเหล่านั้น
โชคดีที่มีวิธีแก้ไขสำหรับเรื่องนั้นด้วย...
วิธีรับส่วนประกอบที่สองบนวัตถุเกม (การจัดการหลายส่วนประกอบ)
Get Component, Get Component in Children และ Get Component in Parent เหมาะอย่างยิ่งสำหรับการดึงส่วนประกอบเดียวจากวัตถุเกมอื่น
อย่างไรก็ตาม…
หากคุณใช้ส่วนประกอบประเภทเดียวกันหลายรายการบนออบเจ็กต์ อาจเป็นเรื่องยากที่จะทราบว่าส่วนประกอบใดที่จะถูกดึงออกมาจริงๆ
ตามค่าเริ่มต้น เมื่อใช้วิธีการรับส่วนประกอบ Unity จะส่งคืนส่วนประกอบแรกของประเภทนั้นจากบนลงล่าง โดยเริ่มจากวัตถุเกมที่ถูกเรียกใช้
นั่นหมายความว่าหากมีสองส่วนประกอบที่เป็นประเภทเดียวกัน ส่วนประกอบแรกจะถูกส่งคืน
แต่ถ้าคุณต้องการเข้าถึงองค์ประกอบที่สองล่ะ?
วิธีหนึ่งคือการเรียงลำดับส่วนประกอบใหม่เพื่อให้ส่วนประกอบที่คุณต้องการมาเป็นอันดับแรก
และถ้ามันได้ผลสำหรับคุณก็ทำอย่างนั้น
อย่างไรก็ตาม…
หากออบเจ็กต์อื่นเข้าถึงส่วนประกอบในลักษณะเดียวกัน การเรียงลำดับใหม่อาจทำให้เกิดปัญหากับสคริปต์อื่นที่อาจต้องอาศัยลำดับออบเจ็กต์บางอย่าง
หรือคุณสามารถใช้ Get Components เพื่อดึงส่วนประกอบทั้งหมดของประเภทที่กำหนดจากออบเจ็กต์เกม จากนั้นเลือกจากส่วนประกอบเหล่านั้น
นี่คือวิธีการทำงาน...
ขั้นแรก สร้างอาร์เรย์ประเภทส่วนประกอบที่คุณพยายามดึงข้อมูล:
แบบนี้:
แหล่งที่มาของเสียงสาธารณะ [] แหล่งที่มาของเสียง;
สังเกตวงเล็บเหลี่ยมหลังประเภทตัวแปร ซึ่งทำเครื่องหมายว่าเป็นอาร์เรย์
หากคุณไม่คุ้นเคยอาร์เรย์พวกมันอนุญาตให้คุณเก็บตัวแปรประเภทเดียวกันหลายตัวไว้ในตัวแปรอาเรย์ตัวเดียวเหมือนกับรายการ (แต่อย่าสับสนกับค่าจริงรายการใน Unityซึ่งคล้ายกับอาร์เรย์ แต่สามารถเรียงลำดับใหม่ได้)
จากนั้น เติมอาร์เรย์โดยใช้ GetComponents, GetComponentsInChildren หรือ GetComponentsInParent
แบบนี้:
แหล่งที่มาของเสียง = GetComponents<แหล่งที่มาของเสียง>();
สิ่งนี้จะเพิ่มการอ้างอิงไปยังอาร์เรย์สำหรับทุกองค์ประกอบที่ตรงกันที่พบ
เมื่อคุณเติมอาร์เรย์แล้ว แต่ละองค์ประกอบจะมีดัชนีของตัวเอง โดยเริ่มจาก 0:
แต่ละองค์ประกอบ Array มีดัชนีเริ่มต้นจากศูนย์ซึ่งเป็นดัชนีแรก
หากต้องการเข้าถึงองค์ประกอบเฉพาะของอาร์เรย์ เพียงพิมพ์ชื่อของตัวแปรอาร์เรย์ ตามด้วยดัชนีขององค์ประกอบที่คุณต้องการเข้าถึงในวงเล็บเหลี่ยม
แบบนี้:
PlayerHealth ระดับสาธารณะ: MonoBehaviour { AudioSource สาธารณะ [] audioSources; เครื่องเล่น AudioSource สาธารณะAudioSource; เป็นโมฆะเริ่มต้น () { แหล่งที่มาของเสียง = GetComponents <แหล่งที่มาของเสียง> (); playerAudioSource = แหล่งที่มาของเสียง [1]; }}
ในตัวอย่างนี้ ฉันได้ตั้งค่าแหล่งเสียงของเครื่องเล่นตัวแปรไปที่ที่สองรายการในอาร์เรย์แหล่งกำเนิดเสียง
คุณจะสังเกตเห็นว่าฉันป้อนหมายเลข 1 เพื่อรับรายการที่สอง ไม่ใช่ 2 เนื่องจากดัชนีอาร์เรย์เริ่มนับที่ 0 ไม่ใช่ 1
แม้ว่าวิธีนี้จะช่วยแยกความแตกต่างระหว่างส่วนประกอบหลายประเภทที่เป็นประเภทเดียวกัน แต่ก็อาจเสี่ยงต่อข้อผิดพลาดได้เช่นกัน เนื่องจากยังคงสามารถเปลี่ยนสิ่งที่ส่งคืนได้โดยการจัดเรียงใหม่หรือลบส่วนประกอบใดส่วนประกอบหนึ่งออก
ด้วยเหตุนี้ บางครั้งจึงควรตั้งค่าการอ้างอิงด้วยตนเอง (หากเป็นตัวเลือก) หรือแบ่งส่วนประกอบออกเป็นหลาย ๆ วัตถุในเกม (หากการทำเช่นนี้จะป้องกันความสับสนระหว่างวัตถุเหล่านั้น)
และแม้ว่าการสร้างอ็อบเจ็กต์หลายรายการให้กับแต่ละคอมโพเนนต์เดี่ยวอาจดูขัดกับสัญชาตญาณ แต่ถ้าช่วยหลีกเลี่ยงข้อผิดพลาดและทำให้โปรเจ็กต์ของคุณสามารถจัดการได้มากขึ้น ความแตกต่างของประสิทธิภาพเพียงเล็กน้อยก็มีแนวโน้มที่จะคุ้มค่า
รับส่วนประกอบช้าหรือไม่?
การใช้ Get Component อาจเป็นวิธีที่เป็นประโยชน์ในการแคชการอ้างอิง
อย่างไรก็ตาม…
เนื่องจาก Unity จะทำการค้นหาส่วนประกอบของออบเจ็กต์ทุกครั้งที่คุณใช้มัน จึงช้ากว่าการใช้การอ้างอิงที่แคชไว้ที่มีอยู่
นั่นเป็นเหตุผลว่าทำไมจึงเป็นความคิดที่ดีที่จะใช้ Get Component บ่อยที่สุดเท่าที่จะเป็นไปได้
เช่นหนึ่งครั้งใน Start เพื่อแคชการอ้างอิงถึงส่วนประกอบหรือบางครั้งในเกมเมื่อตั้งค่าวัตถุใหม่
อย่างไรก็ตาม ตราบใดที่คุณไม่ได้เรียก Get Component ใน Update หรือเรียกจากออบเจ็กต์จำนวนมากพร้อมกัน คุณไม่น่าจะประสบปัญหาด้านประสิทธิภาพเมื่อใช้งาน
รับ Component vs การตั้งค่าตัวแปรสาธารณะในตัวตรวจสอบ (ที่จะใช้)
ดังนั้น… ตัวเลือกใดที่ดีกว่าสำหรับการอ้างอิงถึงส่วนประกอบหรือสคริปต์
เป็น Get Component หรือคุณควรตั้งค่าตัวแปรสาธารณะใน Inspector ด้วยตนเอง
โดยทั่วไป เมื่อคุณมีการอ้างอิงถึงสคริปต์หรือส่วนประกอบแล้ว ทั้งสองวิธีจะทำงานเหมือนกัน และวิธีหนึ่งไม่จำเป็นต้องดีกว่าอีกวิธีหนึ่ง (ตราบใดที่คุณไม่ได้เรียกใช้ Get Component บ่อยครั้ง เช่น ในการอัปเดต)
ดังนั้นเมื่อตัดสินใจว่าจะใช้วิธีใด ควรพิจารณาว่าวิธีใดจะจัดการได้ง่ายกว่าสำหรับคุณ
ตัวอย่างเช่น... หากคุณกำลังสร้างออบเจ็กต์เกม Prefab และกำลังใช้ส่วนที่แตกต่างกันหลายส่วน โดยแต่ละส่วนมีสคริปต์ของตัวเองที่อ้างถึงส่วนอื่นๆ และส่วนประกอบของออบเจ็กต์โดยรวม ไม่สมเหตุสมผลเลยในการใช้ Get Component เพื่อเชื่อมต่อทุกสิ่ง ด้วยกัน. การตั้งค่าการเชื่อมต่อด้วยตัวเองจะสะดวกกว่าและอาจจัดการได้ง่ายกว่า โดยบันทึกไว้ใน Prefab ที่เสร็จแล้ว
อย่างไรก็ตาม หากคุณได้สร้างส่วนประกอบสคริปต์ที่นำมาใช้ซ้ำได้ซึ่งออกแบบมาเพื่อทำงานชิ้นเดียวเมื่อวางลงบนวัตถุเกม Get Component อาจเป็นวิธีที่มีประโยชน์ในการตั้งค่าโดยอัตโนมัติ
ตัวอย่างเช่น ฉันต้องการสร้างสคริปต์ที่สุ่มการตั้งค่าของแหล่งกำเนิดเสียงใน Start การใช้ Get Component เพื่อตั้งค่าแหล่งกำเนิดเสียงโดยอัตโนมัติจะเป็นการลบขั้นตอนที่ไม่จำเป็นออกไป
จากนั้นฉันก็สามารถเพิ่มมันลงในวัตถุใดๆ ที่มีแหล่งกำเนิดเสียงอยู่และปล่อยให้สคริปต์ตั้งค่าเอง
มีประโยชน์ใช่มั้ย?
มีปัญหาเพียงอย่างเดียว
หากฉันลืมเพิ่มแหล่งที่มาของเสียงให้กับออบเจ็กต์เมื่อเพิ่มสคริปต์ จะพยายามเพื่อให้ได้สิ่งที่ไม่มีอยู่ตรงนั้น ซึ่งทำให้เกิดข้อผิดพลาด
ดังนั้นหากฉันต้องการใช้ Get Component เพื่อทำให้การตั้งค่าสคริปต์เป็นแบบอัตโนมัติ ฉันจะแน่ใจได้อย่างไรว่าสคริปต์นั้นมีทุกสิ่งที่ต้องการ
นั่นคือสิ่งที่ Require Component เข้ามา
วิธีการใช้งาน Require Component
ต้องการส่วนประกอบเป็นแอตทริบิวต์คลาสที่บังคับให้ Unity ตรวจสอบส่วนประกอบบางประเภทเมื่อเพิ่มสคริปต์ลงในวัตถุ
นอกจากนี้ยังป้องกันไม่ให้คุณลบส่วนประกอบที่จำเป็นออกจากออบเจ็กต์หากสคริปต์อื่นต้องการให้อยู่ที่นั่น
ตัวอย่างเช่น ฉันสามารถระบุได้ว่าสคริปต์ Randomise Audio ของฉันต้องการแหล่งที่มาของเสียงจึงจะทำงานได้
แบบนี้:
[ต้องการส่วนประกอบ (ประเภทของ (แหล่งเสียง))]
นอกจากนี้ยังใช้ได้กับส่วนประกอบประเภทอื่นๆ และแน่นอนว่ารวมถึงคลาสสคริปต์อื่นๆ ด้วย:
[ต้องการส่วนประกอบ(ประเภทของ (PlayerHealth))]
ต้องการส่วนประกอบเป็นแอตทริบิวต์ของคลาส ดังนั้นจึงถูกเพิ่มไว้ข้างหน้าการประกาศคลาสในวงเล็บเหลี่ยม
แบบนี้:
โดยใช้ UnityEngine;[RequireComponent(typeof(AudioSource))]public class RandomiseAudioSource : MonoBehaviour{ // เริ่มถูกเรียกก่อนการอัพเดตเฟรมแรกถือเป็นโมฆะ Start() { AudioSource source = GetComponent(); source.volume = สุ่มช่วง (0.5f, .75f); }}
ตอนนี้เมื่อเพิ่มสคริปต์นี้ไปยังออบเจ็กต์ หากไม่มีแหล่งที่มาของเสียง แหล่งที่มาจะถูกเพิ่มให้ฉัน
และหากฉันพยายามลบแหล่งกำเนิดเสียงนั้นในขณะที่ยังจำเป็นอยู่ Unity จะหยุดฉัน
Require Component ช่วยให้คุณหลีกเลี่ยงการก่อวินาศกรรมโครงการของคุณเอง
นอกจากนี้ยังใช้งานได้ในขณะรันไทม์ ยกเว้นว่าแทนที่จะเห็นคำเตือนเหมือนในภาพด้านบน หากคุณพยายามทำลายส่วนประกอบที่สคริปต์กำหนด ส่วนประกอบนั้นจะถูกปิดใช้งาน แทนที่จะถูกลบออก
แต่จงจำไว้ว่าต้องการส่วนประกอบใช้งานได้เฉพาะเมื่อมีการเพิ่มหรือลบสคริปต์เท่านั้น
ตัวอย่างเช่น หากคุณเพิ่มสคริปต์ให้กับออบเจ็กต์เกม จากนั้นให้ระบุแอตทริบิวต์ Require Component ในภายหลัง Unity จะไม่ตรวจสอบส่วนประกอบนั้น ซึ่งอาจทำให้เกิดข้อผิดพลาดได้
การใช้ Require Component ร่วมกับ Get Component เป็นวิธีที่ยอดเยี่ยมในการตั้งค่าส่วนประกอบสคริปต์โดยอัตโนมัติ ขณะเดียวกันก็ตรวจสอบให้แน่ใจว่ามีทุกสิ่งที่ต้องการ
และสิ่งนี้สามารถทำให้การตั้งค่าการอ้างอิงบนออบเจ็กต์ที่เชื่อมโยงอย่างใกล้ชิดง่ายขึ้นและตรงไปตรงมามากขึ้น
แต่…
คุณจะได้รับการอ้างอิงถึงวัตถุที่แตกต่างไปจากเดิมอย่างสิ้นเชิงได้อย่างไร?
เช่นเดียวกับผู้เล่น ศัตรู หรือส่วนประกอบของเกมที่แยกจากกันโดยสิ้นเชิงจำนวนเท่าใดก็ได้
โดยไม่ทำให้โครงการของคุณยุ่งเหยิง
ค้นหาวัตถุต่าง ๆ ในฉาก
เมื่อคุณเริ่มสร้างส่วนต่าง ๆ ของเกม คุณจะต้องการแต่ละส่วนเพื่อเชื่อมต่อและสื่อสารกันอย่างไม่ต้องสงสัย
และแม้ว่าวิธีที่ง่ายที่สุดในการทำเช่นนี้คือการตั้งค่าด้วยตนเองในตัวตรวจสอบ แต่ก็ไม่สามารถทำได้เสมอไป
ตัวอย่างเช่น คุณอาจสร้างอินสแตนซ์ของศัตรูที่ต้องการค้นหาผู้เล่น
หรือคุณอาจต้องการระบบเกมที่แตกต่างกันเพื่อให้สามารถตั้งค่าได้เมื่อเริ่มด่าน
โชคดีที่มีตัวเลือกมากมายสำหรับการค้นหาวัตถุในฉาก
เริ่มจากตัวเลือกพื้นฐานกันก่อน
ค้นหา GameObject ตามชื่อ
วิธีง่ายๆ วิธีหนึ่งในการรับการอ้างอิงถึงวัตถุคือการใช้ชื่อของมัน
แบบนี้:
FindObject คลาสสาธารณะ: MonoBehaviour { ผู้เล่น GameObject สาธารณะ; เป็นโมฆะเริ่ม () { ผู้เล่น = GameObject.Find ("ผู้เล่น"); }}
สิ่งนี้จะส่งคืนออบเจ็กต์เกมที่ตรงกับสตริงที่ตรงกันทุกประการ
ในกรณีนี้คือ “ผู้เล่น”
คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ ดังนั้นคุณจะต้องพิมพ์ชื่อของออบเจ็กต์ให้ตรงกันทุกประการ
มันอาจจะช้าเช่นกัน...
คล้ายกับ Get Component วิธีการนี้จะค้นหาวัตถุในเกมใน Scene และด้วยเหตุนี้จึงไม่ใช่ตัวเลือกที่มีประสิทธิภาพมากที่สุด
ดังนั้นในขณะที่มันใช้ได้หาเป็นความคิดที่ดีที่จะใช้มันบ่อยๆ เช่น ในลูปการอัปเดตของคุณ
และถึงแม้จะง่ายและสะดวกมาก แต่การค้นหาวัตถุตามชื่อก็มีข้อเสียบางประการ
ตัวอย่างเช่น หากชื่อของออบเจ็กต์เปลี่ยนแปลงเมื่อใดก็ตาม สคริปต์จะไม่สามารถค้นหาได้อีกต่อไป
และถ้าคุณมีวัตถุที่มีชื่อเดียวกันหลายชิ้นในฉาก ก็ไม่รับประกันว่าวัตถุใดจะถูกส่งกลับ
ซึ่งแตกต่างจากการค้นหาอื่นๆ เช่น Get Component ซึ่งสามารถคาดเดาได้มากกว่า (ค้นหาจากบนลงล่าง)
หากต้องการแยกความแตกต่างระหว่างออบเจ็กต์ที่มีชื่อเดียวกัน คุณสามารถใช้เครื่องหมายทับเพื่อระบุออบเจ็กต์พาเรนต์และออบเจ็กต์ลูกได้ เช่นเดียวกับที่คุณทำในไดเร็กทอรีไฟล์
แบบนี้:
ผู้เล่น = GameObject.Find("PlayerObject/ผู้เล่น");
อย่างไรก็ตาม วิธีการนี้ยังเสี่ยงต่อการเปลี่ยนชื่อและการเปลี่ยนแปลงลำดับชั้นของวัตถุ ซึ่งทั้งสองอย่างนี้จะทำให้วิธีนี้หยุดทำงาน
แล้ว… มีตัวเลือกอื่นใดอีกบ้างในการค้นหาวัตถุของเกมที่อื่นในฉาก?
วิธีค้นหาวัตถุด้วยแท็กใน Unity
แท็กใน Unity จะมีประโยชน์ในการแยกวัตถุเฉพาะออกจากกัน
เช่น ในการชนกัน ซึ่งคุณอาจต้องการตรวจสอบว่าวัตถุชนกับผู้เล่นหรือไม่ หรือผู้เล่นชนกับศัตรูหรือไม่โดยการตรวจสอบแท็ก
แบบนี้:
โมฆะส่วนตัว OnTriggerEnter (Collider อื่น ๆ ) { ถ้า (other.tag == "ผู้เล่น") { // ทำอะไรสักอย่าง } }
นั่นไม่ใช่ทั้งหมด
แท็กยังสามารถใช้เพื่อค้นหาและจัดเก็บการอ้างอิงวัตถุเกมได้โดยใช้ค้นหาด้วยแท็ก.
ขั้นแรกให้กำหนดแท็กให้กับวัตถุของเกมที่คุณต้องการค้นหา
ตัวอย่างเช่น แท็กผู้เล่น:
ตั้งค่าแท็กของวัตถุในตัวตรวจสอบ หรือสร้างแท็กใหม่ด้วยเพิ่มแท็ก...
คุณยังสามารถสร้างแท็กใหม่โดยใช้เพิ่มแท็ก… ตัวเลือก.
จากนั้นค้นหาวัตถุที่ใช้ค้นหาด้วยแท็ก.
แบบนี้:
ผู้เล่น = GameObject.FindWithTag ("ผู้เล่น");
ค้นหาด้วยแท็กจะส่งคืนวัตถุแรกที่พบในฉากพร้อมกับแท็กที่ตรงกัน
อย่างไรก็ตาม…
เช่นเดียวกับการค้นหาด้วยชื่อ หากฉากของคุณมีวัตถุหลายรายการที่มีแท็กเดียวกัน ก็ไม่รับประกันว่าคุณจะได้สิ่งที่คุณต้องการ
นั่นเป็นเหตุผลว่าทำไมการใช้บ่อยจึงเป็นประโยชน์ค้นหาด้วยแท็กเพื่อค้นหาวัตถุเมื่อคุณรู้ว่าเป็นวัตถุเดียวที่มีแท็กนั้น เช่น เครื่องเล่น เป็นต้น
แต่ถ้าคุณต้องการอ้างอิงถึงออบเจ็กต์ทั้งหมดในฉากด้วยแท็กทั่วไปล่ะ
แท็กศัตรูเช่น...
วิธีรับวัตถุหลายรายการด้วยแท็ก
เช่นเดียวกับการค้นหาด้วยแท็กค้นหาวัตถุด้วยแท็กค้นหาวัตถุในฉากที่มีแท็กแนบอยู่ โดยเพิ่มวัตถุทั้งหมดลงในอาร์เรย์
แบบนี้:
FindObject คลาสสาธารณะ: MonoBehaviour { ศัตรู GameObject [] สาธารณะ; เป็นโมฆะเริ่ม () { ศัตรู = GameObject.FindGameObjectsWithTag ("ศัตรู"); }}
สิ่งนี้มีประโยชน์สำหรับการค้นหาวัตถุบางประเภทจำนวนหนึ่งพร้อมกัน
อย่างไรก็ตาม…
เช่นเดียวกับการค้นหาด้วยแท็กค้นหาวัตถุด้วยแท็กอาจทำงานช้าได้ ดังนั้น ควรหลีกเลี่ยงการใช้งานบ่อยๆ เช่น ในลูปการอัปเดต
ค้นหาวัตถุประเภท
ค้นหาวัตถุประเภทอาจมีประโยชน์ในการค้นหาวัตถุเกมที่ใช้สคริปต์หรือส่วนประกอบเดียวกัน
ตัวอย่างเช่น คุณสามารถใช้มันเพื่อค้นหาแหล่งที่มาของเสียงทั้งหมดในฉาก
แบบนี้:
FindObject คลาสสาธารณะ: MonoBehaviour { AudioSource สาธารณะ [] audioSourcesInScene; เป็นโมฆะเริ่มต้น () { audioSourcesInScene = FindObjectsOfType (); foreach (AudioSource audioSource ใน audioSourcesInScene) { audioSource.mute = true; } }}
สคริปต์นี้จะค้นหาแหล่งที่มาของเสียงทุกแหล่งในฉากและปิดเสียงแต่ละรายการ
หรือคุณสามารถค้นหาวัตถุทุกชิ้นที่มีสคริปต์ด้านสุขภาพอยู่...
แบบนี้:
FindObject คลาสสาธารณะ: MonoBehaviour { PlayerHealth สาธารณะ [] objectWithHealth; เป็นโมฆะเริ่มต้น () { objectWithHealth = FindObjectsOfType (); }}
สิ่งที่คุณต้องการมันเพื่อค้นหาวัตถุประเภทอาจเป็นวิธีที่รวดเร็วและง่ายดายในการจัดการกลุ่มของออบเจ็กต์ที่ทั้งหมดใช้ฟังก์ชันการทำงานเดียวกัน
แต่... เช่นเดียวกับฟังก์ชันอื่นๆ ที่เกี่ยวข้องกับการค้นหาฉาก วิธีการนี้อาจช้า
และแม้ว่าโปรเจ็กต์ของคุณมีขนาดเล็กอาจไม่ก่อให้เกิดปัญหาใดๆ ก็ตาม แต่เมื่อเกมของคุณมีขนาดใหญ่ขึ้น การใช้วิธีนี้ในการค้นหาและจัดการคอลเลกชั่นของออบเจ็กต์อาจทำได้ช้าและจัดการได้ยาก
จากตัวอย่างก่อนหน้านี้ แทนที่จะค้นหาศัตรูทุกตัวหรือทุกออบเจ็กต์ที่มีพลังชีวิต การให้ออบเจ็กต์เพิ่มตัวเองลงในรายการที่ออบเจ็กต์และสคริปต์อื่นสามารถตรวจสอบได้ง่ายกว่าแทน
และนั่นไม่ใช่ทั้งหมด คุณอาจพบว่าเมื่อคุณสร้างโปรเจ็กต์ของคุณ สคริปต์จำนวนมากขึ้นเรื่อยๆ จำเป็นต้องแบ่งปันข้อมูลเดียวกัน
ข้อมูล เช่น คะแนน ตำแหน่งของผู้เล่น สุขภาพ หรือจำนวนศัตรูในฉาก
หากต้องการให้แต่ละสคริปต์เชื่อมต่อกับสคริปต์อื่นๆ ที่จำเป็นต้องใช้อาจกลายเป็นเรื่องยากในการจัดการอย่างรวดเร็ว
แล้วอะไรคือวิธีที่ดีที่สุดในการจัดการตัวแปรเหล่านั้นทั้งหมดในเกม และทำให้มันพร้อมใช้งานสำหรับสคริปต์อื่นด้วย
โดยไม่ทำลายทุกสิ่ง
ตัวแปรโกลบอลใน Unity
สิ่งที่เป็นตัวแปรทั่วโลกในความสามัคคี?
โดยทั่วไปตัวแปรร่วมใน Unity จะอ้างอิงถึงตัวแปรที่มีค่าเดียว จุดอ้างอิงเดียว และสามารถเข้าถึงได้จากสคริปต์ใดๆ
เมื่อเปรียบเทียบกับอินสแตนซ์ตัวแปรบนสคริปต์ปกติ ซึ่งอาจมีหลายอินสแตนซ์ที่แตกต่างกัน โดยแต่ละอินสแตนซ์มีค่าที่แตกต่างกันบนวัตถุในเกมหลายตัว วัตถุประสงค์ของตัวแปรร่วมคือเพื่อติดตามค่าของตัวแปรตัวเดียวเพื่อให้สคริปต์อื่น ๆ อ้างอิง
คุณอาจใช้สิ่งนี้เพื่อสุขภาพของผู้เล่น คะแนน เวลาที่เหลือ หรือมูลค่าที่สำคัญต่อเกมอื่นๆ
คุณจะสร้างตัวแปรโกลบอลใน Unity ได้อย่างไร?
มีหลายวิธีในการสร้างตัวแปรโกลบอลใน Unity.
วิธีที่ง่ายที่สุดในการสร้างตัวแปรโกลบอลคือการใช้คงที่ตัวแปร.
ตัวแปรคงที่ใน Unity
ตัวแปรคงที่ใน Unity เป็นตัวแปรที่แชร์โดยอินสแตนซ์ทั้งหมดของคลาส
หากต้องการทำเครื่องหมายตัวแปรเป็นแบบคงที่ใน Unity เพียงเพิ่มคำหลักแบบคงที่เมื่อประกาศ
แบบนี้:
PlayerHealth ระดับสาธารณะ: MonoBehaviour { สุขภาพโฟลตสาธารณะแบบคงที่ = 100;}
จากนั้น หากต้องการเข้าถึงตัวแปร แทนที่จะอ้างอิงถึงอินสแตนซ์ของคลาส คุณสามารถเข้าถึงได้ผ่านคลาสนั้นเอง
แบบนี้:
hp ลอย = PlayerHealth.health;
วิธีนี้ใช้ได้ผลเนื่องจากตัวแปรเป็นแบบสาธารณะและแบบคงที่ ดังนั้นแม้ว่าจะมีสคริปต์นี้หลายอินสแตนซ์ สคริปต์ทั้งหมดก็จะใช้ค่าเดียวกัน
นอกจากนี้ยังสามารถทำเครื่องหมายทั้งคลาสเป็นแบบคงที่ได้
แบบนี้:
PlayerHealth ระดับสาธารณะคงที่ { สุขภาพลอยคงที่สาธารณะ; เกราะลอยคงที่สาธารณะ;}
อย่างไรก็ตาม โปรดทราบว่าเนื่องจากคลาสแบบคงที่ไม่สามารถสืบทอดมาจาก MonoBehaviour ได้ ดังนั้น คุณจะต้องลบการสืบทอด “: MonoBehaviour” ปกติออกจากส่วนท้ายของการประกาศคลาส
คุณคงได้รับการอภัยที่คิดว่าสิ่งนี้จะทำให้ทุกตัวแปรในคลาสคงที่โดยอัตโนมัติ มันไม่ได้
การทำเครื่องหมายคลาสเป็นแบบคงที่นั้นหมายความว่าไม่สามารถสร้างอินสแตนซ์ในฉากได้
คุณจะต้องทำเครื่องหมายแต่ละตัวแปรและวิธีการภายในคลาสให้เป็นแบบคงที่เพื่อให้ทำงานได้ตามที่คุณคาดหวัง
การใช้สถิติเพื่อสร้างผู้จัดการเกมซิงเกิลตัน
วิธีหนึ่งของการใช้ตัวแปรคงที่เพื่อจัดการการอ้างอิงและค่าส่วนกลางคือการสร้างตัวจัดการเกมซิงเกิลตัน
Singleton ใช้จุดเข้าแบบคงที่จุดเดียวผ่านการอ้างอิงอินสแตนซ์แบบคงที่
วิธีนี้ทำให้สคริปต์อื่นสามารถเข้าถึง Singleton และตัวแปรต่างๆ ได้โดยไม่ต้องอ้างอิงถึงสคริปต์นั้นก่อน
ตัวอย่างเช่น คุณสามารถสร้างสคริปต์ชื่อ Game Manager ที่เก็บตัวแปรต่างๆ เช่น คะแนน เวลาเล่นเกม และค่าที่สำคัญอื่นๆ และเพิ่มลงในวัตถุในฉาก
จากนั้นสคริปต์ Game Manager จะเก็บการอ้างอิงแบบคงที่ไว้กับตัวมันเอง ซึ่งสคริปต์อื่นสามารถเข้าถึงได้
แบบนี้:
GameManager ระดับสาธารณะ: MonoBehaviour { อินสแตนซ์ GameManager คงที่สาธารณะ { รับ; ชุดส่วนตัว } ผู้เล่นโฟลตสาธารณะสุขภาพ=100; เวลาเล่นเกมโฟลตสาธารณะ = 90; โมฆะส่วนตัว Awake () { อินสแตนซ์ = สิ่งนี้; }}
สังเกตรับ; ชุดส่วนตัวบรรทัดหลังการประกาศตัวแปร? ฟังก์ชัน Get และ Set จะเปลี่ยนตัวแปรให้เป็น aคุณสมบัติซึ่งพูดง่ายๆ ก็คือเพิ่มชั้นการควบคุมวิธีที่สคริปต์อื่นเข้าถึงตัวแปร สามารถใช้เพื่อเรียกใช้โค้ดเพิ่มเติมเมื่อตั้งค่าหรือรับตัวแปร หรือในกรณีนี้ เพื่อป้องกันไม่ให้สคริปต์อื่นตั้งค่าอินสแตนซ์
จำเป็นต้องเพิ่มสคริปต์นี้ให้กับออบเจ็กต์ในฉากเพื่อให้ทำงานได้ ดังนั้นตัวคลาสจึงไม่คงที่ แต่เป็นเพียงการอ้างอิงอินสแตนซ์เท่านั้น
อย่างไรก็ตาม เมื่อเป็นเช่นนั้น สคริปต์อื่นๆ จะสามารถเข้าถึงตัวแปรสาธารณะของผู้จัดการได้โดยการอ้างอิงคลาส Game Manager และอินสแตนซ์
แบบนี้:
เป็นโมฆะเริ่ม () { Debug.Log (GameManager.Instance.playerHealth); Debug.Log(GameManager.Instance.gameTime); }
นี่เป็นตัวอย่างพื้นฐานของรูปแบบการออกแบบซิงเกิลตัน ในทางปฏิบัติ เมื่อใช้ Singletons ควรใช้ความระมัดระวังเป็นพิเศษในการจัดการการเข้าถึงตัวแปร และเพื่อหลีกเลี่ยงการสร้างอินสแตนซ์ตัวจัดการเกมที่ซ้ำกันในฉาก ดูส่วนลิงก์ท้ายบทความนี้เพื่อดูข้อมูลขั้นสูงเพิ่มเติมเกี่ยวกับการใช้ Singletons
เมื่อใดจึงจะใช้ตัวแปรคงที่ใน Unity ได้
เมื่อใช้ในการกลั่นกรองและตามวัตถุประสงค์ที่ตั้งใจไว้ คลาสคงที่ การอ้างอิง และตัวแปรจะมีประโยชน์อย่างยิ่ง
อย่างไรก็ตาม…
แม้ว่าพวกเขาจะสะดวกมาก แต่การพึ่งพาบ่อยเกินไปหรือผิดวิธีอาจทำให้เกิดปัญหาได้
ทำไม
มันขึ้นอยู่กับว่าคุณใช้งานมันอย่างไร
คุณอาจเคยได้ยินมาว่าการใช้สถิติคงที่ (และ Singletons สำหรับเรื่องนั้น) ถือเป็นแนวปฏิบัติที่ไม่ดี
แต่ข้อตกลงคืออะไร?
เหตุใดคุณจึงใช้ตัวแปรคงที่ไม่ได้
เมื่อใดจึงจะใช้ได้?
จะเกิดอะไรขึ้นถ้าคุณทำอย่างนั้น?
สาเหตุหลักประการหนึ่งในการหลีกเลี่ยงสถิติคือการป้องกันปัญหาการห่อหุ้มและการพึ่งพา เนื่องจากสถิติไม่เฉพาะเจาะจงกับวัตถุหรือฉากใดวัตถุหนึ่ง แต่แตกต่างจากอินสแตนซ์คลาสตรงที่เข้าถึงได้ทั่วทั้งโปรเจ็กต์แทน
แน่นอนว่านี่คือเหตุผลว่าทำไมการใช้ตัวแปรคงที่จึงสะดวกมาก คุณสามารถเข้าถึงได้จากทุกที่
แต่สิ่งเดียวกันที่ทำให้สแตติกใช้งานง่ายก็อาจทำให้เกิดปัญหาได้เช่นกันเมื่อโปรเจ็กต์ของคุณเติบโตขึ้น
ตัวอย่างเช่น การเชื่อมต่อสคริปต์หลายตัวเข้าด้วยกันอย่างไม่ระมัดระวังผ่านการอ้างอิงแบบคงที่ เพียงเพราะมันเป็นวิธีที่ง่ายในการดำเนินการ อาจทำให้เกิดการขึ้นต่อกันที่ไม่พึงประสงค์ระหว่างสคริปต์เหล่านั้นได้
การถอดอันหนึ่งออกอาจทำให้อันหนึ่งพังหรืออาจกลายเป็นเรื่องยากที่จะจัดการ
และแม้ว่าจะมีเหตุผลที่ถูกต้องตามกฎหมายในการใช้สถิติ แต่เมื่อโครงการมีขนาดใหญ่ขึ้น การใช้อย่างไม่ระมัดระวังในลักษณะนี้อาจทำให้เกิดปัญหาที่ยากต่อการค้นหา ทดสอบ หรือแก้ไขได้
คุณไม่ควรใช้ตัวแปรคงที่เลยหรือ?
ในความเป็นจริง การใช้ตัวแปรคงที่เท่าที่จำเป็นก็ไม่ใช่ปัญหาเสมอไป โดยเฉพาะอย่างยิ่งหากโปรเจ็กต์ของคุณมีขนาดเล็ก และตราบใดที่คุณเข้าใจวิธีใช้งานที่ถูกต้อง
ดังนั้นวิธีที่ถูกต้องในการใช้งานคืออะไร?
โดยทั่วไป คุณสามารถใช้ตัวแปรคงที่สำหรับบางสิ่งได้ หากไม่มีมากกว่าหนึ่งตัวแปรเลย
และฉันก็หมายความว่าไม่เคย…
ตัวอย่างเช่น มันอาจจะสมเหตุสมผลที่จะเก็บสุขภาพของผู้เล่นไว้ในตัวแปรคงที่ใช่ไหม
แบบนี้:
PlayerHealth คลาสคงที่สาธารณะ { โฟลตสาธารณะ hp = 100;}
จากนั้นจึงเข้าถึงได้ง่ายด้วยสคริปต์ผู้เล่น สคริปต์ศัตรู และ UI
อย่างไรก็ตาม…
หากคุณตัดสินใจในภายหลังว่าจะเพิ่มการรองรับผู้เล่นหลายคนแบบร่วมมือกันในเกมของคุณ และคุณได้ฮาร์ดโค้ดเส้นทางตัวแปรคงที่ “PlayerHealth.hp” ลงในทุกสคริปต์ที่ต้องเข้าถึง อาจเป็นเรื่องยากสำหรับ จากนั้นให้คุณค้นหาและเปลี่ยนแปลงทุกการอ้างอิงถึงตัวแปรนั้นเพื่อให้มันใช้งานได้กับผู้เล่นคนที่สอง
นอกจากนี้ สคริปต์สุขภาพที่เป็นส่วนประกอบที่นำมาใช้ซ้ำได้นั้นเหมาะอย่างยิ่งสำหรับผู้เล่นและศัตรู
การอ้างอิงตัวแปรสุขภาพแบบคงที่โดยตรงทำให้ไม่สามารถใช้สคริปต์ซ้ำกับสิ่งอื่นใดได้
แล้วคุณจะใช้ประโยชน์จากตัวแปรที่เข้าถึงได้ทั่วโลกโดยที่ยังคงไว้ซึ่งโมดูลาร์ได้อย่างไร
นั่นคือที่มาของ Scriptable Objects...
ตัวแปรวัตถุที่สามารถเขียนสคริปต์ได้ใน Unity
ออบเจ็กต์ที่สามารถเขียนสคริปต์ได้ใน Unity คือที่เก็บข้อมูลที่ช่วยให้คุณสามารถจัดเก็บข้อมูลได้อย่างอิสระจากอินสแตนซ์ของสคริปต์ในฉาก
ทำงานแตกต่างจากคลาสปกติและคลาสแบบคงที่ แต่มีประโยชน์อย่างเหลือเชื่อสำหรับการสร้างโปรเจ็กต์ที่ง่ายต่อการจัดการ
พวกมันมีประโยชน์อย่างน่าอัศจรรย์
ไม่มีจริงๆ!
แล้วพวกเขาทำงานอย่างไร?
เมื่อคุณสร้างคลาสปกติ คลาสนั้นจะอยู่ในโปรเจ็กต์และอินสแตนซ์ของคลาสนั้นจะถูกสร้างขึ้นในฉากเมื่อมีการเพิ่มคลาสเหล่านั้นให้กับออบเจ็กต์เกมเป็นส่วนประกอบ
อินสแตนซ์คลาสของวัตถุแต่ละรายการในฉากจะเก็บค่าตัวแปรของตัวเองไว้(ตัวแปรสมาชิก) และออบเจ็กต์ที่แตกต่างกันแต่ละออบเจ็กต์มีข้อมูลไม่ซ้ำกัน เช่นสุขภาพของศัตรู เป็นต้น
ซึ่งเหมาะอย่างยิ่งสำหรับการสร้างข้อมูลที่เฉพาะเจาะจงกับวัตถุในฉาก
อย่างไรก็ตาม…
เมื่อคุณสร้างคลาส Scriptable Object คลาสจะทำหน้าที่เป็นเทมเพลตและแต่ละอินสแตนซ์จะถูกสร้างขึ้นภายในโปรเจ็กต์ในโฟลเดอร์ Assets
ไม่อยู่ในฉาก..
โดยพื้นฐานแล้วออบเจ็กต์ที่สามารถเขียนสคริปต์ได้คือทรัพย์สินที่อยู่ในโฟลเดอร์โปรเจ็กต์ของคุณ แต่สามารถอ้างอิงได้โดยตรงจากอินสแตนซ์สคริปต์ในฉาก
ตอนนี้…
ถ้าฉันเสียคุณไปก็ไม่ต้องกังวล เพราะคุณอาจเคยใช้ทรัพย์สินในลักษณะนี้มาก่อน
ตัวอย่างเช่น คลิปเสียงทำงานในลักษณะเดียวกันกับออบเจ็กต์ที่สามารถเขียนสคริปต์ได้
คลิปเสียงเป็นทรัพย์สินในโปรเจ็กต์ ในขณะที่แหล่งที่มาของเสียงเป็นส่วนประกอบที่อยู่บนวัตถุของเกมในฉาก
ส่วนประกอบแหล่งกำเนิดเสียงจะอ้างอิงคลิปเสียงเพื่อเล่น และการเปลี่ยนคลิปเสียงก็ทำได้ง่ายเหมือนกับการลากคลิปใหม่ไปยังช่องคลิปของแหล่งกำเนิดเสียง
ออบเจ็กต์ที่สร้างสคริปต์ได้ทำงานในลักษณะเดียวกันกับแอสเซทอื่นๆ เช่น คลิปเสียง
เป็นไปได้ที่แหล่งเสียงสองแหล่งจะอ้างอิงคลิปเสียงเดียวกันโดยไม่จำเป็นต้องอ้างอิงถึงกัน
แหล่งเสียงไม่จำเป็นต้องรู้ว่ามีแหล่งอื่นอยู่ แต่ทั้งคู่ก็สามารถใช้คลิปเสียงเดียวกันได้
และการถอดอันหนึ่งออกไปก็ไม่สร้างความแตกต่างให้กับอีกอัน
มันเป็นโมดูลาร์ทั้งหมด
ซึ่งเป็นพลังของ Scriptable Objects… ความเป็นโมดูล
แล้วคุณจะใช้ประโยชน์จากพลังของ Scriptable Objects เพื่อจัดการการอ้างอิงวัตถุและตัวแปรร่วมได้อย่างไร
นี่คือวิธีการทำ...
วิธีสร้างตัวแปรโกลบอลโดยใช้ Scriptable Objects ใน Unity
ในตัวอย่างต่อไปนี้ ฉันจะสร้างค่าสุขภาพของผู้เล่นอีกครั้ง ยกเว้นในครั้งนี้โดยใช้ Scriptable Object:
การเปิดเผยข้อมูลอย่างครบถ้วนและให้เครดิตเมื่อครบกำหนด ฉันค้นพบวิธีการใช้ Scriptable Objects เป็นตัวแปรจากการพูดคุยของ Unite ครั้งแรกโดย Ryan Hipple ในขณะที่ฉันใช้ Scriptable Objects เพื่อสร้างตัวแปรพื้นฐานทั่วโลก การพูดคุยของ Ryan เน้นอย่างเจาะลึกว่าคุณจะใช้ประโยชน์จาก Scriptable Objects เพื่อจัดโครงสร้างเกมของคุณในแบบโมดูลาร์ได้อย่างไร ฉันขอแนะนำให้ดูแบบเต็มและฉันจะทิ้งลิงก์ไปยังวิดีโอไว้ท้ายบทความนี้
นี่คือวิธีการทำงาน...
ก่อนอื่น ฉันต้องสร้างสคริปต์เทมเพลตที่เนื้อหา Scriptable Object จะได้รับมา
1. สร้างสคริปต์ C# ใหม่ในโฟลเดอร์โครงการ:
จนถึงตอนนี้ คุณอาจเพิ่มสคริปต์ใหม่เป็นส่วนประกอบเท่านั้น หากต้องการสร้างเนื้อหาสคริปต์ใหม่ในโปรเจ็กต์โดยไม่ต้องเพิ่มลงในออบเจ็กต์ ให้คลิกขวาที่มุมมองโปรเจ็กต์แล้วเลือกสคริปต์ C# ใหม่
- โทรเลยตัวแปรลอยตัวเทมเพลตออบเจ็กต์สคริปต์ได้นี้จะสร้างเทมเพลตสำหรับออบเจ็กต์สคริปต์ตัวแปรลอยใดๆ ที่คุณสร้างขึ้น
- เปิดมันขึ้นมาและแทนที่พฤติกรรมโมโนกับScriptableObjectเพื่อให้สืบทอดมาจากคลาส Scriptable Object
FloatVariable ระดับสาธารณะ: ScriptableObject
- ต่อไปประกาศ กลอยสาธารณะตัวแปรที่เรียกว่าค่า.
มูลค่าลอยตัวสาธารณะ
- สุดท้าย ก่อนการประกาศชั้นเรียน ให้เพิ่มบรรทัดที่อ่านว่า:
[CreateAssetMenu(menuName = "ตัวแปรโฟลต")]
ซึ่งช่วยให้สามารถสร้างเนื้อหาของอ็อบเจ็กต์ที่สามารถเขียนสคริปต์ได้จากเมนูคลิกขวาของมุมมองโปรเจ็กต์ นี่เป็นสิ่งสำคัญ เนื่องจากหากไม่มีสิ่งนี้ คุณจะไม่สามารถสร้างออบเจ็กต์ที่สามารถเขียนสคริปต์ได้จากเทมเพลตนี้ได้อย่างง่ายดาย
สคริปต์ของคุณควรมีลักษณะดังนี้:
ใช้ UnityEngine;[CreateAssetMenu(menuName = "Float Variable")]คลาสสาธารณะ FloatVariable : ScriptableObject{ ค่าโฟลตสาธารณะ;}
นั่นคือทั้งหมดที่จำเป็นในการสร้างเทมเพลต ตอนนี้เพื่อสร้างอินสแตนซ์สคริปต์ที่สามารถเก็บข้อมูลที่ไม่ซ้ำใครได้
2. จากนั้น สร้างเนื้อหาตัวแปร Float จากเทมเพลต Scriptable Object
- ในมุมมองโครงการคลิกขวาและเลือกสร้าง > ตัวแปรโฟลต
- ตั้งชื่อที่สร้างขึ้นใหม่วัตถุสคริปต์ได้บางสิ่งบางอย่างที่สมเหตุสมผล เช่นผู้เล่นHP
- เลือกวัตถุ Scriptable ที่สร้างขึ้นใหม่และตั้งค่าเริ่มต้นในตัวตรวจสอบ เช่น 100
ตั้งค่าเริ่มต้นในตัวตรวจสอบ ฉันใช้ 95 ที่นี่ แต่ 100 น่าจะสมเหตุสมผลมากกว่า คุณว่ามั้ย?
ค่าของอ็อบเจ็กต์ที่สามารถเขียนสคริปต์ได้ แตกต่างจากตัวแปรสมาชิก คือไม่ต้องรีเซ็ตเมื่อฉากเปลี่ยนแปลง หรือแม้แต่เมื่อคุณออกจากโหมดการเล่น ซึ่งหมายความว่าคุณจะต้องเปลี่ยนค่าด้วยตนเองเมื่อต้องการรีเซ็ต
ในตัวอย่างนี้ หากต้องการรีเซ็ตสุขภาพของผู้เล่น คุณสามารถสร้างวินาทีได้ตัวแปรลอยตัว, เรียกว่าสุขภาพเริ่มต้นที่เก็บสุขภาพเริ่มต้นของผู้เล่น จากนั้นเพียงตั้งค่าสุขภาพของผู้เล่นที่จุดเริ่มต้นของฉากโดยใช้ค่านั้นเป็นข้อมูลอ้างอิง
ตอนนี้คุณได้สร้างเทมเพลตตัวแปรและอินสแตนซ์ตัวแปรแล้ว สคริปต์อื่นจะใช้ค่านั้นได้อย่างไร
3. อ้างอิงวัตถุที่สามารถเขียนสคริปต์ได้จากสคริปต์ในฉาก
สุดท้าย หากต้องการอ้างอิงค่าสุขภาพของผู้เล่นทั่วโลกจากสคริปต์ใดๆ:
- สร้างตัวแปร FloatVariable สาธารณะบนสคริปต์อื่น ๆ เรียกมันว่า playerHealth เป็นตัวอย่าง (ชื่อไม่จำเป็นต้องตรงกับ Scriptable Object)
ผู้เล่น FloatVariable สาธารณะสุขภาพ;
- ใน Inspector ให้ตั้งค่า FloatVariable เพื่ออ้างอิง PlayerHP Scriptable Object (คลิกและลาก หรือใช้การเลือกวงกลม)
การเลือกอ็อบเจ็กต์ที่สามารถเขียนสคริปต์ได้ก็เหมือนกับการเลือกเนื้อหาอื่นๆ
จากนั้นคุณสามารถใช้ตัวแปรได้เหมือนกับทศนิยมอื่นๆ อย่าลืมใช้ Dot Operator เพื่อเข้าถึงค่าจริง
แบบนี้:
ใช้ UnityEngine; PlayerHealth ระดับสาธารณะ: MonoBehaviour { public FloatVariable playerHealth; เป็นโมฆะเริ่มต้น () { Debug.Log ("สุขภาพของผู้เล่นคือ: " + playerHealth.value); } TakeDamage เป็นโมฆะ(ความเสียหายลอยตัว) { playerHealth.value -= DamageTaken; }}
เคล็ดลับ:อย่าลืมพิมพ์ผู้เล่นHealth.valueเมื่อเข้าถึงตัวแปร ไม่ใช่แค่ playerHealth ซึ่งจะใช้งานไม่ได้
ตอนนี้ สคริปต์ใดๆ ก็สามารถเข้าถึงตัวแปรเดียวกันได้โดยตรง โดยไม่ต้องอ้างอิงถึงออบเจ็กต์อื่น
มีอะไรที่ยอดเยี่ยมเกี่ยวกับเรื่องนี้?
และมันดีกว่าตัวแปรคงที่อย่างไร?
ฉันจะอธิบาย...
ตัวแปรโกลบอลของ Scriptable Object เทียบกับตัวแปรคงที่
การใช้ Scriptable Objects สำหรับตัวแปรร่วมสามารถยืดหยุ่นได้มากกว่าการใช้ตัวแปรคงที่มาก
เนื่องจากในขณะที่การอ้างอิงแบบคงที่ถูกเขียนลงในสคริปต์โดยตรง ตัวแปรตามวัตถุที่สามารถเขียนสคริปต์ได้ต้องการเพียงการอ้างอิงไปยังตัวแปรของสิ่งนั้นพิมพ์.
มันดีกว่ายังไงล่ะ?
ในตัวอย่างข้างต้น ฉันใช้ตัวแปร Scriptable Object เพื่อติดตามความสมบูรณ์ของผู้เล่น ในกรณีนี้คือการใช้อินสแตนซ์ของเทมเพลต Float Variable ของฉัน
ดังนั้น ทุกครั้งที่ต้องการเข้าถึงสุขภาพของผู้เล่น (จากสคริปต์ใดๆ ในโปรเจ็กต์) ฉันเพียงแค่อ้างอิงไปยัง Float Variable Scriptable Object แล้วจึงปล่อยอินสแตนซ์ PlayerHP
แบบนี้:
ผู้เล่น FloatVariable สาธารณะสุขภาพ;
สิ่งที่ยอดเยี่ยมเกี่ยวกับเรื่องนี้ก็คือ ฉันสามารถใช้งานได้เหมือนกับการสลับคลิปเสียงใดๆFloat Variable Scriptable Object เข้ามาแทนที่
เช่น สำหรับผู้เล่นคนที่สอง
สิ่งที่ฉันต้องทำคือสร้างตัวแปร Scriptable Object Float Variable ที่เรียกว่า Player2HP และใช้สิ่งนั้นแทน
ทั้งหมดนี้โดยไม่ต้องแก้ไขสคริปต์เลย
ความยืดหยุ่นและความเป็นโมดูลนี้ทำให้ตัวแปร Scriptable Object มีประโยชน์อย่างเหลือเชื่อ
ตอนนี้ถึงตาคุณแล้ว
ตอนนี้ฉันอยากได้ยินจากคุณ
คุณจะใช้เคล็ดลับเหล่านี้ในโครงการของคุณอย่างไร
อะไรที่ใช้ได้ผลดีสำหรับคุณในอดีต?
อะไรไม่มี? และคุณอยากรู้อะไรเมื่อคุณเริ่มต้นใช้งาน Unity ครั้งแรก?
ไม่ว่าจะเป็นอะไรแจ้งให้เราทราบโดยแสดงความคิดเห็นด้านล่าง
จากผู้เชี่ยวชาญ:
Ryan Hipple อธิบายวิธีหลีกเลี่ยง Singletons และใช้ Scriptable Objects เป็นตัวแปร:
Jason Weimann อธิบายรูปแบบ Singleton ประเภทต่างๆ ที่เขาใช้และข้อผิดพลาดทั่วไปบางประการที่ควรหลีกเลี่ยง:
โดย จอห์น ลีโอนาร์ด ชาวฝรั่งเศส
ผู้เชี่ยวชาญด้านเสียงเกมและนักพัฒนามือสมัครเล่นที่กระตือรือร้น
รับเคล็ดลับการพัฒนาเกมส่งตรงถึงกล่องจดหมายของคุณ
รับเคล็ดลับและคำแนะนำที่เป็นประโยชน์และพื้นฐานการพัฒนาเกมอย่างเชี่ยวชาญด้วยวิธีง่ายๆ พร้อมบทช่วยสอนและคำแนะนำเชิงลึก
สินทรัพย์ Unity ที่ช่วยประหยัดเวลาที่ฉันชื่นชอบ
ตอบแทน (ที่ระบบการจัดการอินพุตที่ดีที่สุด)
ต่อสายแล้วเป็นทรัพย์สินการจัดการอินพุตที่ขยายระบบอินพุตเริ่มต้นของ Unity ซึ่งก็คือ Input Manager ซึ่งเพิ่มการปรับปรุงและการสนับสนุนที่จำเป็นมากสำหรับอุปกรณ์สมัยใหม่ พูดง่ายๆ ก็คือ มีความล้ำหน้ากว่า Input Manager เริ่มต้นมาก และมีความน่าเชื่อถือมากกว่า Input System ใหม่ของ Unityเมื่อฉันทดสอบทั้งสองระบบฉันพบว่า Rewired นั้นใช้งานง่ายอย่างน่าประหลาดใจและมีคุณลักษณะครบถ้วน ดังนั้นฉันจึงเข้าใจว่าทำไมทุกคนรักมัน.
DOTween Pro (ควรสร้างไว้ใน Unity)
สินทรัพย์ที่มีประโยชน์มาก ควรถูกสร้างไว้ใน Unity แล้ว ยกเว้นแต่ว่ามันไม่ใช่ดอทวีน โปรเป็นเครื่องมือแอนิเมชั่นและกำหนดเวลาที่ให้คุณสร้างแอนิเมชันอะไรก็ได้ใน Unity คุณสามารถย้าย จางลง ปรับขนาด หมุนได้โดยไม่ต้องเขียนฟังก์ชัน Coroutines หรือ Lerp
ประหยัดง่าย (ไม่มีเหตุผลที่จะไม่ใช้)
บันทึกง่ายทำให้การจัดการเกมบันทึกและซีเรียลไลซ์ไฟล์เป็นเรื่องง่ายมากใน Unity มากเสียจนในช่วงเวลาที่ใช้ในการสร้างระบบบันทึก เทียบกับต้นทุนในการซื้อ Easy Save ฉันไม่แนะนำให้สร้างระบบบันทึกของคุณเองเนื่องจาก Easy Save มีอยู่แล้ว
เครดิตรูปภาพ
- เทมเพลต Flat Platformerโดยกลม
- ไอคอนที่สร้างโดยฟรีปิคจากwww.flaticon.com