Skip to main content

SerializeReferences Sample

A turret whose weapons and their effects are picked in the Inspector, plus assets broken on purpose for you to repair.

The dummy changes color and shrinks as the configured weapons and effects deal damage.The dummy changes color and shrinks as the configured weapons and effects deal damage.

The dummy changes color and shrinks as the configured weapons and effects deal damage.

Open it​

  1. Import the sample: Tools → Aspid 🐍 → FastTools → Welcome → Samples → Import on SerializeReferences.
  2. Open Scenes/SerializeReferences.unity and enter Play Mode: the primary weapon and the sidearms take turns hitting the dummy, and the Console reports every hit.

Try​

Exit Play Mode and select Loadout.

Weapons, a nested burn effect, and modifiers in the Loadout Inspector.Weapons, a nested burn effect, and modifiers in the Loadout Inspector.

Weapons, a nested burn effect, and modifiers in the Loadout Inspector.

  1. Pick a class. Open the Primary dropdown: a searchable picker lists every concrete IWeapon, grouped under Weapons/Melee and Weapons/Ranged by [TypeSelectorDisplay]. DebugWeapon is left out with Hidden. Pick Shotgun: its fields appear under the dropdown.
  2. Shared data survives a switch. In Sidearms, set the Pistol's Damage to 37, switch it to Shotgun and back: Damage is still 37, because both classes declare _damage.
  3. Lists. Press + on Sidearms: the picker opens instead of copying the last element, and the new element gets its own instance. In Play Mode it joins the firing rotation.
  4. Narrowing. Melee Backup is declared IWeapon, but [TypeSelector(typeof(IMelee))] offers only Sword. The Weapon field of each Holster slot is narrowed the same way one level down, inside a plain [Serializable] class: [TypeSelector(typeof(IRanged))] offers only ranged weapons. Neither field joins the firing rotation.
  5. Nested references. The Railgun in Primary has a Charge Effect, a [SerializeReference] of its own with its own dropdown. It holds a BurnEffect, so the dummy catches fire when the railgun hits.
  6. Abstract base. On Hit is a StatusEffect: the picker offers BurnEffect and FreezeEffect, never the abstract class.
  7. Generics.
    • Damage Modifier is a Modifier<float>: DamageModifier and Modifier<Single> are offered and created at once.
    • Perks is a List<IModifier>: besides the closed subclasses it offers the open Modifier<T>, which asks for T on a second page.
    • Only DamageModifier changes the damage; Loadout → Log Loadout in the component's context menu prints the values of the others.
  8. Required field. Set Primary to <None>: a notice appears under the field. Save the scene, and Project References → Scan Project and CI runs with -srGateRequired report the field as a violation; a player build does not check it (what each run checks).
  9. Header menu. Right-click a field header for copy and paste, templates, usages and a new script: every item.

Repair​

The assets in Presets/ and Prefabs/ store types that are missing or out of date.

  1. Fix one asset. Select Presets/BrokenWeaponPreset.asset: Weapon stores a GhostWeapon that does not exist, and the Missing type notice under the field offers Fix. Press it and pick Pistol: Damage 25 and Magazine Size 8 are kept.
  2. Fix a group. Open Tools → Aspid 🐍 → FastTools → Project References and press Scan Project: the three GhostWeapon entries of BrokenArsenalPreset.asset form one group, and Fix all repairs them at once.
  3. A suggested class. Presets/MovedWeaponPreset.asset stores Pistol under an old namespace. Its notice offers → Pistol, and its group in Project References offers Smart Fix → Pistol; neither applies itself.
  4. A migration. Presets/RenamedWeaponPreset.asset stores CrossbowLauncher, and the class is now Crossbow with [MovedFrom]: the Inspector already shows Crossbow, only the file is out of date. Migrate all → Crossbow in Project References writes the new name into the file.
  5. A prefab. Select Prefabs/BrokenLoadout.prefab in the Project window. Sidearms[2] is a missing GhostCrossbow with Fix; Sidearms[0] and [1] point at one Pistol and are marked Shared reference #N, and Make unique gives an element its own copy. The Asset References tab lists every reference of the prefab.

To repeat the repair, import the sample again and overwrite its files.

IMGUI inspector​

WeaponPreset has an IMGUI inspector, Scripts/Editor/WeaponPresetEditor.cs: plain EditorGUILayout.PropertyField() calls draw the field and the list, with the picker, Fix and the list's + working as in UI Toolkit. For fields without [TypeSelector], see Custom inspector.

Where to look​

FileShows
Scripts/Loadout.csEvery field shape: single, list, narrowed, container, abstract base, closed and open generics, Required
Scripts/Weapons/The IWeapon hierarchy, [TypeSelectorDisplay] groups, a Hidden class, [MovedFrom] on Crossbow, a nested reference in Railgun
Scripts/Effects/, Scripts/Modifiers/An abstract base and an open generic class
Scripts/WeaponPreset.cs, Presets/, Prefabs/The repair scenarios
Scripts/Editor/WeaponPresetEditor.csAn IMGUI inspector of plain PropertyField calls

Reference: SerializeReference Selector and SerializeReference Tooling.