Developedia
Developedia
Objektumok azonosítása string-gel

Objektumok azonosítása string-gel

Jelen lecke tekinthető GameObject-ek azonosításaGameObject-ek azonosítása című fejezet folytatásának. Java

A név szerint történő keresés és azonosítás problémája, hogy felesleges redundanciát hoz be a projectbe és ezáltal törékenyebbé teszi azt, a szükségesnél.

Egy objektum neve legalább két helyen lesz így jelen a projektben: Egyszer az editorban és egyszer a kódban. Itt a redundancia. Ezek közül bármelyiket írja át a fejlesztő, az hibás működéshez vezet. És ami még rosszabb, ezt a hibát nem is garantált, hogy hamar észrevesszük.

Ez talán nem hat nagy gondnak, akkor érzi át igazán a fejlesztő a probléma súlyát, amikor egy bizonyos méreten túllép a projekt. Ekkor eljuthat a fejlesztés arra a pontra, amikor senki nem mer semmit átnevezni mert attól fér, hogy az valahol szerepel a kódban és eltör vele valamit.

Megoldás lehet, hogy minden átnevezés előtt mindenki rákeres a kódban az adott névre. Ez azonban csak egy csúnya és lassú megkerülése a problémának. Nem beszélve arról, hogy a projekten dolgozhatnak dizájnerek is, akik nem jártasak a kódszerkesztésben.

Amit most leírtam egy esernyőprobléma, ami nem korlátozódik csak a GameObject-ek nevére. A Unity-ben több esetben is név szerint kell vagy lehet hivatkozni programozási elemekre és ezen string összehasonlítások mindegyikével ugyanaz a gond, mint amit előbb leírtam:

  • GameObject.Find(”GameObject neve”);
  • Invoke(”Metódus neve”);
  • UI elemek név szerint hívnak metódusokat
  • Animációs eventek név szerint hívnak metódusokat
  • Tag-ek
  • LayerMask.NameToLayer
  • GUI és EditorGUI metódusok paramétereiben név szerint kell hivatkozni más metódusokra
  • …

Megoldási lehetőségek

  1. Használhatunk név vagy tag-ek lekérdezése helyett komponens lekérdezést.
  2. SomeMonoBehaviour component = FindObjectOfType<SomeMonoBehaviour >();

    Ekkor akár azért is létrehozhatunk egy MonoBehaviour komponenst, hogy azt mint afféle azonosítót hozzáadhassuk egy vagy több GameObject-hez.

    Ám erre legtöbbször nincs szükség. Gyakran van egy konkrét komponens, amit keresünk.

  3. Lehetséges, létrehozni egy ScriptableObject típust csak arra a célra, hogy vele azonosítsunk GameObject-eket. Ekkor külön komponenst, kell létrehozni, azért hogy a fenti ScriptableObject-ekkel be tudjunk jelölni egy GameObject-et.
    1. ‣
      Kód

      Ezzel a rendszerrel leválthatjuk teljesen a Unity tag rendszert, ami kizárólag névösszehasonlításon alapul. A mi rendszerünk előnyei:

    2. Nem string összehasonlításon alapul: stabilabb
    3. Több tag is hozzárendelhető egy GameObject-hez
    4. Ha később szeretnénk, akkor beállítások is adhatók az összes vagy bizonyos tag-ekhez. (Lehet, hogy le kell ehhez származnia Tag osztályból.)
    5. Sokkal gyorsabb
  4. A C# 6.0 verziótól kezdődően a nyelv része a nameof(), amivel lekérdezhető egy programozási elem neve string-ben. Ez sok esetben teljesen megoldja a gondunkat.
  5. void Start()
    {
        Invoke(nameof(Destroy), 2.5f);
    }
  6. Eseményvezérelt architektúra használata
  7. Például UI gombok lenyomására kódból iratkozunk fel és nem az editor felületen.

Hol nem tudjuk kikerülni a string összehasonlítást?

Eddigi tapasztalataim szerint egyedül az animáció kapcsán nem tudjuk megkerülni, hogy string-ek által azonosítsunk programozási elemeket.

  1. Animációnál név szerint hivatkozunk a módosítandó paraméterekre
  2. Animációs paraméterekre kódból névvel kell hivatkozni.
  3. Animációs események név szerint hivatkoznak meghívandó metódusokra.
Logo

Főoldal

Blog

Elmélet

3D Studio

Adatvédelmi nyilatkozat

GY.I.K.

Házirend

Szerző: Marosi Csaba / marosi.csaba@3d-studio.hu

DiscordGitHubLinkedIn