Menu
CoddyTech

Serialisierbare Klassen

Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 18 von 64.

Ein Skript mit vielen Einstellungen erhält im Inspector eine lange, flache Liste. Eine einfache C#-Klasse kann sie gruppieren: Markiere sie mit [System.Serializable], und ein Feld dieses Klassentyps wird als Aufklappfeld angezeigt, das nach dem Feld benannt ist und die Felder der Klasse enthält. Eine Klasse kann für mehrere Felder und mehrere Skripte verwendet werden:

[System.Serializable]
public class Stats
{
    public float speed = 2f;
    public int damage = 10;
}

public class Enemy : MonoBehaviour
{
    public Stats normal;
    public Stats enraged;
    private Stats current;

    void Start()
    {
        current = normal;
    }

    void Update()
    {
        transform.Translate(0f, 0f, current.speed * Time.deltaTime);
    }

    public void Enrage()
    {
        current = enraged;
    }
}

Der Inspector zeigt zwei Aufklappfelder, Normal und Enraged, jeweils mit Speed und Damage. Jeder Enemy erhält seine eigenen beiden Stats-Objekte, die in seinem eigenen Inspector ausgefüllt werden, und der Code liest sie als normal.speed aus. Unity erstellt diese Objekte, wenn es das Skript lädt. Daher ist normal niemals null, auch ohne = new Stats(), und die Feldinitialisierungen (2 und 10) bestimmen, womit ein neuer Enemy beginnt. Eine Struktur funktioniert mit dem Attribut auf dieselbe Weise: [System.Serializable] public struct Range { public float min; public float max; }. Wie Vector3 wird sie beim Zuweisen kopiert.

Das Attribut ist erforderlich, weil Unity nur die Typen speichert, die ihm dafür angegeben werden. Ohne es ist die Klasse im Inspector unsichtbar: Es gibt kein Aufklappfeld, dort festgelegte Werte werden nicht gespeichert, und Unity erstellt das Objekt nicht. Daher löst normal.speed eine NullReferenceException aus. Innerhalb der Klasse gelten die üblichen Inspector-Regeln: öffentliche Felder oder private Felder mit [SerializeField], niemals Eigenschaften oder statische Felder.

challenge icon

Aufgabe

Einfach

Fasse die Einstellungen jedes Lichtkegels in einer Struktur zusammen.

  1. Deklariere oberhalb von Flashlight public struct Beam mit den öffentlichen Feldern Color color, float range und float angle. Markiere sie mit [System.Serializable], damit sie im Inspector angezeigt wird.
  2. Ersetze die sechs einzelnen Felder durch public Beam wide; und public Beam focused;.
  3. Setze in Apply() die drei Werte des Lichts anhand von focusedOn ? focused : wide.

Drücke auf „Spielen“ und die Leertaste: Der Lichtkegel erreicht den Kristall. Klicke dann auf „Prüfen“.

Probier es selbst

using UnityEngine;
using UnityEngine.InputSystem;

public class Flashlight : MonoBehaviour
{
    public Color wideColor = Color.white;
    public float wideRange = 5f;
    public float wideAngle = 60f;
    public Color focusedColor = Color.white;
    public float focusedRange = 10f;
    public float focusedAngle = 30f;
    private bool focusedOn;
    private Light lamp;

    void Start()
    {
        lamp = GetComponent<Light>();
        Apply();
    }

    void Update()
    {
        if (Keyboard.current.spaceKey.wasPressedThisFrame)
        {
            focusedOn = !focusedOn;
            Apply();
        }
    }

    void Apply()
    {
        lamp.color = focusedOn ? focusedColor : wideColor;
        lamp.range = focusedOn ? focusedRange : wideRange;
        lamp.spotAngle = focusedOn ? focusedAngle : wideAngle;
    }
}

Alle Lektionen in Spielarchitektur in Unity

Übe selbstständig: Unity-Playground