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.
Aufgabe
EinfachFasse die Einstellungen jedes Lichtkegels in einer Struktur zusammen.
- Deklariere oberhalb von
Flashlightpublic struct Beammit den öffentlichen FeldernColor color,float rangeundfloat angle. Markiere sie mit[System.Serializable], damit sie im Inspector angezeigt wird. - Ersetze die sechs einzelnen Felder durch
public Beam wide;undpublic Beam focused;. - Setze in
Apply()die drei Werte des Lichts anhand vonfocusedOn ? 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
1Komponenten statt Hierarchien
Kleine KomponentenEin Basis-GegnerskriptAbstrakte KomponentenZusammenwirkende KomponentenRückblick: Modulares GeschützRückblick: Zwillingskanone4Serialisierte Daten
Serialisierbare KlassenListen im InspectorEnums im InspectorRückblick: Loot-TabelleRückblick: Beute auswürfeln2Schnittstellen in Unity
IDamageableSchnittstellen und TryGetComponentGetComponentsZusammenfassung: InteraktionstasteZusammenfassung: Nächstes in Reichweite5ScriptableObjects
Daten-AssetsWaffenwerteGemeinsame EinstellungenDen Wind speichernWellen als DatenRückblick: Item-DatenbankRückblick: Im Shop einkaufen8Wiederverwendbarer Code
ErweiterungsmethodenEin generisches SingletonGenerische HilfsmethodenRückblick: FindNearestÜbe selbstständig: Unity-Playground