SerializeReference Selector
Реализацию выбирают прямо в инспекторе — из списка с поиском, без своего редактора.
Быстрый старт
| До — Unity API | После — FastTools |
|---|---|
| |
Какие классы в списке
Список строится по типу поля; атрибут может сузить его дополнительными типами.
public interface IMelee : IWeapon { }
public sealed class Sword : IMelee { }
public abstract class StatusEffect { }
public class Modifier<T> : IModifier { }
public sealed class DamageModifier : Modifier<float> { }
| Тип поля | Что в списке |
|---|---|
Интерфейс IWeapon | Классы, реализующие его: Crossbow, Pistol, Railgun, Shotgun, Sword |
IWeapon и typeof(IMelee) в атрибуте | Классы, подходящие под оба: Sword |
Абстрактный класс StatusEffect | Его наследники: BurnEffect, FreezeEffect |
Modifier<float> | Наследник DamageModifier и сам Modifier<Single> |
List<IModifier> | AmmoModifier, DamageModifier, NameModifier и Modifier<T> с выбором T |
- В инспекторе runtime-объекта нет классов из editor-only сборок (
UnityEditor, asmdef только для Editor, папкиEditor): билд плеера не сможет их создать. - Аргументы generic-класса выводятся из типа поля; если вывести их нельзя, окно спрашивает каждый и предлагает только типы, которые Unity умеет сериализовать.
- Ограничение можно взять и из другого поля.
[TypeSelectorDisplay]настраивает строку класса в списке или скрывает класс.
Обязательное поле
[TypeSelector(Required = true)]
[SerializeReference] private IWeapon _primary;
С Required = true пустое поле показывает Required reference is not set; подробнее — в разделе Обязательное поле.
Списки
В списке с [TypeSelector] кнопка «+» открывает выбор класса и добавляет новый экземпляр, а <None> — пустой элемент. При нескольких выбранных объектах каждый получает свой экземпляр, всё в одной группе Undo.


Смена класса
Новый экземпляр получает значения полей с теми же именами:
| Поле | Pistol | → Shotgun |
|---|---|---|
| Damage | 37 | 37 |
| Magazine Size | 12 | — |
| Pellets | — | 8, начальное значение |


Вложенная ссылка с тем же именем переходит в новый класс тем же экземпляром, а не копией.
Скрипт .cs, перетащенный из Project на заголовок поля, так же меняет класс поля на свой.
Меню заголовка
Правый клик по заголовку поля:
| Пункт | Что делает |
|---|---|
| Copy Serialize Reference | Копирует класс и данные поля; копия живёт до перезагрузки домена |
| Paste Serialize Reference | Вставляет копию в поле подходящего типа; копия пустого поля очищает его |
| Make Unique Reference | Даёт полю собственную копию общей ссылки; у необщей ссылки пункта нет |
| Find Usages of Pistol | Ищет класс в проекте через Unity Search |
| Link to Existing → … | Указывает поле на экземпляр из другого поля того же объекта |
| Create New Script… | Создаёт [Serializable] класс под тип поля и назначает его после компиляции |
| Save as Template… | Сохраняет значение под именем; шаблоны хранятся в настройках редактора на этом компьютере, не в проекте |
| Paste Template → … | Создаёт экземпляр из шаблона; в списке только подходящие полю |
| Paste Template → Remove Missing (N)… | Удаляет шаблоны, класс которых не загружается; виден, только если такие шаблоны есть |
Copy/Paste и шаблоны не переносят вложенные поля [SerializeReference]: скопированный Railgun вставится без _chargeEffect.
Общие ссылки
Два поля объекта могут указывать на один экземпляр: правка через одно видна в другом. Такие поля помечены Shared reference #N, а Make unique даёт полю собственную копию вместе с вложенными ссылками.


Продублированный элемент списка получает собственный экземпляр, а не ссылку на тот же. За это отвечает настройка Auto de-alias duplicated list elements в общих настройках, по умолчанию она включена.
Восстановление потерянного типа
После переименования, переноса или удаления класса у поля появляется Missing type, а данные остаются в ассете.


| Действие | Что делает |
|---|---|
| Fix | Открывает выбор класса, включая скрытые через Hidden |
| → Pistol | Назначает предложенный класс; причина в подсказке: то же имя, то же имя в другом регистре или похожее имя |
На ассете Fix переписывает файл, и Undo его не отменит.
В сцене и Prefab Mode исправление остаётся в памяти: Undo его отменяет, а сохранение делает окончательным и очищает историю Undo объекта. Такое исправление возвращает только простые поля верхнего уровня: вложенные объекты, массивы, списки, векторы, цвета и ссылки на объекты получают значения по умолчанию.
Когда Fix нет
| Случай | Что делать |
|---|---|
| Выбрано несколько объектов | Выберите один: до этого Missing type не показывается |
| В сцене или Prefab Mode есть несохранённые изменения | Сохраните: до этого поле показывает <None> без Missing type |
| Экземпляр префаба, класс хранится в исходном префабе | Исправьте исходный префаб, его имя в подсказке |
| Экземпляр префаба, класс задан override | Выберите новый класс на экземпляре или отмените override |
Остальное исправляет SerializeReference Tooling.
Собственный инспектор
Поле с [TypeSelector] в своём редакторе рисует обычный PropertyField: выбор класса и «+» списка появляются сами, вызывать пакет не нужно.
| UI Toolkit — CreateInspectorGUI | IMGUI — OnInspectorGUI |
|---|---|
| |
Если у поля [SerializeReference] нет атрибута [TypeSelector] или элемент списка рисуется отдельно через GetArrayElementAtIndex, PropertyField выбора класса не покажет. Его можно нарисовать в своём редакторе, вызвав один из методов:
| Метод | Что рисует |
|---|---|
SerializeReferenceEditorGUI.CreateField() | Поле в CreateInspectorGUI |
SerializeReferenceEditorGUI.CreateList() | Список в CreateInspectorGUI |
SerializeReferenceEditorGUI.DrawFieldLayout() | Поле в OnInspectorGUI |
SerializeReferenceIMGUIList.Draw() | Список в OnInspectorGUI |
Ограничения поверх типа поля передаются аргументом baseTypes, как типы в [TypeSelector(...)].
Ограничения
- Allow. На
[SerializeReference]не действует — анализаторAFT0002предупредит об этом. - Несовместимые ограничения. Если ни один класс не подходит сразу под тип поля и все типы из атрибута, список классов будет пустым: например,
[TypeSelector(typeof(Sword))]на полеStatusEffect _onHit;. АнализаторыAFT0003,AFT0005иAFT0009предупредят об этом при компиляции.
Пример в пакете
Поля Loadout с этой страницы и ассеты с потерянными типами для Fix есть в примере SerializeReferences.