จะแก้ไขคู่ค่าคีย์ (เช่นพจนานุกรม) ในตัวตรวจสอบของ Unity ได้อย่างไร


18

ฉันมีระบบสะกดคำที่ฉันสร้างหลักการมีดังนี้:

  • แต่ละคาถาเป็นรูปแบบสำเร็จรูปอัตโนมัติ มันมีสคริปต์ที่มีคุณสมบัติบางอย่าง (ความเสียหายพื้นฐานระยะเวลา ... ) ที่สามารถแก้ไขได้ในการตรวจสอบ
  • ฉันมี Spell enum ที่แสดงรายการคาถาที่เป็นไปได้ทั้งหมดในรหัสซึ่งใช้ในตรรกะของเกม
  • เมื่อฉันต้องการเสกคาถาฉันต้องได้รับพรีสแลชของคาถานี้เพื่อยกตัวอย่างและอ่านข้อมูล
  • นักแสดงแต่ละคน (ไม่ว่าจะเป็นผู้เล่นหรือศัตรู) จำเป็นต้องมีรายการอนิเมชั่นที่เป็นไปได้สำหรับคาถา

ปัญหาเกี่ยวกับวิธีที่ฉันพยายามใช้คือ:

  • สำหรับการแสดงรายการแอนิเมชั่นของนักแสดงแต่ละคนฉันสามารถใช้ a Dictionary<Spell, Animation>ได้ แต่พจนานุกรมไม่ได้รับการสนับสนุนจากผู้ตรวจสอบซึ่งทำให้ยากที่จะแก้ไขนักแสดงหลายประเภทได้อย่างง่ายดาย
  • ฉันต้องการวิธีในการเข้าถึง prefab คาถาจาก enum ที่เกี่ยวข้องได้อย่างง่ายดาย ที่นี่ฉันสามารถใช้พจนานุกรมได้ แต่ฉันสามารถอ้างอิงเฉพาะ prefab ในตัวตรวจสอบไม่ใช่ในรหัสซึ่งหมายความว่าฉันจะไม่สามารถเติมพจนานุกรมนี้ได้

ฉันกำลังมองหาวิธีที่จะเชื่อมโยงคาถาของฉันได้อย่างง่ายดาย enums กับ prefabs และภาพเคลื่อนไหวที่สอดคล้องกัน


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

@DM ฉันไม่รู้จัก Unity แต่เหตุผลทั่วไปของคุณฟังดูสมเหตุสมผล กล้าหาญและแก้ไข; การย้อนกลับมีราคาถูก
Anko

คำตอบ:


24

วิธีหนึ่งที่รวดเร็วในการรับคู่คีย์ - ค่าในตัวตรวจสอบของ Unity คือการกำหนด class entry ที่ต่อเนื่องกันได้จากนั้นใช้ array หรือ List <> ของพวกเขา เช่น...

public class SpellAnimationMap : ScriptableObject
{
   [System.Serializable]
   public class SpellAnimationEntry
   {
       public Spell spell;
       public AnimationClip animation;
   }

   public SpellAnimationEntry[] spellAnimations;    
}

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

ผลลัพธ์จะเป็นดังนี้:

ตัวตรวจสอบที่สร้างขึ้นอัตโนมัติ

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

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


แก้ไข:ตอนนี้มันง่ายยิ่งขึ้น - คุณสามารถเพิ่มแอททริบิวนี้เหนือ ScriptableObject ของคุณ:

[CreateAssetMenu(fileName = "fileName.asset", menuName = "Some Folder/Menu Label")]

สิ่งนี้ทำให้ ScriptableObject ในเมนูสร้างของคุณเช่น: สกรีนช็อตแสดงเมนูสร้างที่กำหนดเองใน Unity


คุณสามารถเลือกให้อาร์เรย์เป็นแบบส่วนตัวและต่อเนื่องเพื่อให้ยังคงปรากฏในตัวตรวจสอบ แต่เพิ่ม Public Dictionary (หรือพจนานุกรมส่วนตัวด้วยเมธอด GetAnimation (Spell สะกด) สาธารณะสำหรับลูกค้าเพื่อให้การค้นหามีประสิทธิภาพมากขึ้น ในเมธอด OnEnable () SpellAnimationMap สามารถวนซ้ำผ่านอาร์เรย์ที่มีตัวตรวจสอบเพื่อสร้างพจนานุกรมนี้อีกครั้งแบ่งปันผลประโยชน์ระหว่างอินสแตนซ์ไคลเอ็นต์ทั้งหมดอีกครั้ง (โปรดทราบว่า OnEnable () จะถูกเรียกในตัวแก้ไขเมื่อสินทรัพย์ถูกสร้างขึ้นเป็นครั้งแรกดังนั้นโปรดตรวจสอบให้แน่ใจว่าอาร์เรย์ของคุณไม่เป็นโมฆะก่อนที่คุณจะพยายามอ่าน)

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

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


สิ่งที่ฉันจะทำในขณะที่รอคำตอบดังนั้นฉันจะยอมรับคนนี้
Malharhak

0

อ่านคำอธิบายโดย @DMGregory

สำหรับผู้ที่ชอบตัวอย่าง:

public class SpellHandler : ScriptableObject
{
    public Spell[] keys;
    public Animation[] values;

    private Dictionary<Spell, Animation> dic;

    void Awake()
    {
        int length = keys.Length;
        this.dic= new Dictionary<Spell, Animation>(length);
        for (int i = 0; i < length; i++)
        {
            this.dic.Add(keys[i], values[i]);
        } 
    }    
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.