Serialisierbare Klassen
Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 15 von 50.
Ein Skript mit vielen Einstellungen erhält im Inspector eine lange, flache Liste. Eine einfache C#-Klasse kann sie gruppieren: Kennzeichne sie mit [System.Serializable], und ein Feld dieser Klasse wird als ausklappbarer Bereich angezeigt, der nach dem Feld benannt ist und die Felder der Klasse enthält. Eine Klasse kann mehreren Feldern und mehreren Skripten dienen:
[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 ausklappbare Bereiche, Normal und Enraged, jeweils mit Speed und Damage. Jeder Enemy erhält seine eigenen zwei Stats-Objekte, die im jeweiligen 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 nie null, auch ohne = new Stats(), und die Feldinitialisierer (2 und 10) legen fest, womit ein neuer Enemy beginnt. Ein Struct funktioniert mit dem Attribut genauso: [System.Serializable] public struct Range { public float min; public float max; }. Wie bei Vector3 wird es beim Zuweisen kopiert.
Das Attribut ist erforderlich, weil Unity nur die Typen speichert, die dafür markiert wurden. Ohne das Attribut ist die Klasse im Inspector unsichtbar: Es gibt keinen ausklappbaren Bereich, dort festgelegte Werte werden nicht gespeichert, und Unity erstellt das Objekt nicht, sodass normal.speed eine NullReferenceException auslöst. Innerhalb der Klasse gelten die üblichen Inspector-Regeln: öffentliche Felder oder private Felder mit [SerializeField], niemals Eigenschaften oder statische Felder.
Aufgabe
EinfachDie Taschenlampe des Entdeckers hat zwei Lichtkegel, und mit der Leertaste wechselst du zwischen ihnen: ein breiter, warmer Lichtkegel, um dich umzusehen, und ein fokussierter, kühlweißer Lichtkegel, der tief in die Höhle reicht. Flashlight.cs speichert die drei Einstellungen jedes Lichtkegels in sechs einzelnen Feldern. Die Szene ist bereits so eingerichtet, dass die Einstellungen pro Lichtkegel gruppiert sind, und das Skript muss dazu passen:
- Deklariere eine Struktur
Beammit drei öffentlichen Feldern:color(ein Color),rangeundangle(Floats). Sie muss im Inspector angezeigt werden. - Ersetze die sechs einzelnen Felder durch zwei Beam-Felder,
wideundfocused. In der Szene ist für wide eine warme Farbe, range 6 und angle 80 eingestellt, und für focused ein kühles Weiß, range 15 und angle 25. - Lass
Apply()den Beam des aktuellen Lichtkegels auslesen und damitcolor,rangeundspotAngleder Light festlegen. Der Rest bleibt unverändert: Die Taschenlampe startet mit dem breiten Lichtkegel, und mit der Leertaste wechselst du zwischen den Lichtkegeln.
Drücke Play, drücke die Leertaste, um das hintere Ende der Höhle zu beleuchten, und klicke dann auf Check.
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;
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Spielarchitektur in Unity
1Komponenten statt Hierarchien
Kleine KomponentenEin Basisskript für GegnerAbstrakte KomponentenKomponenten im ZusammenspielRückblick: Modularer Geschützturm4Serialisierte Daten
Serialisierbare KlassenListen im InspectorEnums im InspectorRückblick: Loot-Tabelle7Zustandsautomaten
Zustände als KlassenEin ZustandsautomatÜbergängeGegner-KIWiederholung: Türzustände10Projekt: Arena-Überlebenskampf
Der HeldGegnertypen2Interfaces in Unity
IDamageableInterfaces und TryGetComponentGetComponentsRückblick: Interaktionstaste5ScriptableObjects
Daten-AssetsWaffenwerteGemeinsame EinstellungenWellen als DatenRückblick: Item-Datenbank8Wiederverwendbarer Code
ErweiterungsmethodenEin generisches SingletonGenerische HilfsmethodenRückblick: FindNearest