Изменения
Все значимые изменения Aspid.FastTools документируются в этом файле.
Формат основан на Keep a Changelog, проект следует Semantic Versioning.
[Unreleased]
Добавлено
- Добавлены
RemoveChildrenиRemoveChildrenIf: удаляют несколько дочерних элементов за один вызов и принимают те же перегрузкиparams,IEnumerable,List,SpanиReadOnlySpan, что иAddChildren. - Для
ToggleButtonGroupдобавлены типизированные перегрузкиSetValue,AddValueChanged,RemoveValueChangedиSetLabelдляToggleButtonGroupState, поэтому вызовы вродеAddValueChanged(evt => …)не требуют аргументов типа. - Для
RectIntFieldдобавлен типизированныйSetLabel, поэтомуSetLabel("Area")не требует аргументов типа, как и уRectField. SetRootItemsSelfзаполняетTreeViewилиMultiColumnTreeViewв цепочке:tree.SetAutoExpand(true).SetRootItemsSelf(items).TextField,IntegerField,LongField,UnsignedIntegerField,UnsignedLongField,FloatField,DoubleFieldиHash128Fieldполучили цепочечные сеттеры:SetMaxLength,SetMaskChar,SetDelayed,SetReadOnly,SetPassword,SetPlaceholder,SetHidePlaceholderOnFocus,SetKeyboardType,SetAutoCorrection,SetHideMobileInput,SetHideSoftKeyboard, а для выделения текста —SetSelectable,SetSelectAllOnFocus,SetSelectAllOnMouseUp,SetDoubleClickSelectsWord,SetTripleClickSelectsLine,SetCursorIndex,SetSelectIndex,AddOnCursorIndexChange/RemoveOnCursorIndexChange,AddOnSelectIndexChange/RemoveOnSelectIndexChange. СеттерыITextEditionиITextSelectionк этим полям не применяются. Для других типов значений естьTextInputBaseFieldExtensionsиTextInputBaseFieldTextSelectionExtensions.- Добавлены варианты
AndApplyWithoutUndoдля всех сеттеровSerializedPropertyс немедленным применением, включая перегрузкиSetValue, ссылки на объекты, перечисления и методы изменения размера массивов. - Анализатор
AFT0009(предупреждение) — два базовых типа[TypeSelector]не имеют общего типа, поэтому селектор пуст. - Анализатор
AFT0010(предупреждение) — вызовthis.Marker()не открывает маркер профайлера, потому что генератор не поддерживает его тип: типprivateилиprotected(или вложен в такой тип) либо повторяет имя параметра типа внешнего типа. - Анализатор
AFT0011(предупреждение) — scope изthis.Marker()выброшен (this.Marker();отдельной инструкцией,_ = this.Marker();, локальная переменная, которую никто не читает), поэтому начатый сэмпл никогда не заканчивается. - Потерянные типы
[SerializeReference], заданные override'ами экземпляров префабов (варианты, вложенные префабы, экземпляры префабов в сценах), теперь находятся: build / CI gate считает их потерянными типами, Project References показывает их в карточке Prefab instance overrides, а защита от удаления скрипта и детектор поломок их учитывают. Они не переписываются автоматически: исправьте тип на самом экземпляре или отмените override. Старое имя, которое сопоставляет[MovedFrom], показывается там как ожидающая миграция, потому что Migrate all не переписывает override'ы. В отчёте CI появился последний столбецorigin, для таких строк —override.
Изменено
- Agent Skills для пакета переехали из плагина
aspid-fasttoolsдля Claude Code в Aspid.Claude.Plugins в этот репозиторий (skills/). Устанавливайте их в Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI или другой агент командойnpx skills add VPDPersonal/Aspid.FastTools; плагин больше не публикуется. GetScriptName()переименован вGetDisplayName(), аGetScriptNameWithIndex()— вGetDisplayNameWithIndex(); замените старые вызовы новыми именами. Оба метода возвращаютstring.Emptyдля null и уничтоженных объектов. Поиск индекса компонента использует список из пула вместо временных массивов и LINQ.- Переименованы расширения VisualElement; замените старые вызовы:
SetIsDelayed/SetIsPassword/SetIsReadOnly/SetIsSelectable→SetDelayed/SetPassword/SetReadOnly/SetSelectable;IsFocus→IsFocused,SetFocus/SetBlur→FocusSelf/BlurSelf;EnableInClass/ToggleInClass→EnableClass/ToggleClass;AddStyleSheets/RemoveStyleSheets→AddStyleSheet/RemoveStyleSheet,AddStyleSheetsFromResource/RemoveStyleSheetsFromResource→AddStyleSheetFromResources/RemoveStyleSheetFromResources;SetImageFromResource,SetSpriteFromResource,SetVectorImageFromResource,SetBackgroundImageFromResource→…FromResources;MarkDirtyLayout→MarkDirtyLayoutSelf:IMGUIContainer.MarkDirtyLayout()перекрывал старое расширение, и вызов возвращалvoid; новое имя встраивается в цепочку.
- Классы расширений
BaseFieldExtensionsSetLabel<Type>переименованы вBaseField<Type>Extensions(BaseFieldExtensionsSetLabelInt→BaseFieldIntExtensions), аProgressBarExtensions— вAbstractProgressBarExtensions. Вызовы методов расширения не меняются; меняются только вызовы через имя класса. - У
SetShowMixedValueбольше нет значения аргумента по умолчаниюtrue; передавайте значение явно. SetDirection,SetFill,SetInverted,SetPageSizeиSetShowInputFieldтеперь возвращают собственный тип слайдера (Slider,SliderInt) вместоBaseSlider<TValue>, поэтому цепочка сохраняет члены слайдера. Они принимаютBaseSlider<float>иBaseSlider<int>; открытые перегрузки дляBaseSlider<TValue>удалены. Перегрузки дляBaseSlider<int>находятся в новом классеSliderIntExtensions: вызовы методов расширения не меняются, но вызов черезSliderExtensions.наSliderIntнужно заменить наSliderIntExtensions..- Конструкторы без параметров у
SerializableType/SerializableType<T>больше не публичные: создавайте обёртку черезnew SerializableType(type)илиnew SerializableType<T>(type)(nullдаёт пустую). УSerializableMonoScript/SerializableMonoScript<T>нет публичных конструкторов: объявляйте их сериализуемыми полями и выбирайте скрипт в инспекторе. [TypeSelector]на поле[SerializeReference]теперь предлагает только типы, совместимые со всеми типами атрибута, — по тому же правилу, что уже действовало для полейstringиSerializableType; раньше достаточно было совпасть с одним из них. То же относится кbaseTypesуSerializeReferenceEditorGUI.CreateField,CreateListиDrawFieldLayout. Список альтернатив вродеtypeof(Pistol), typeof(Rifle)теперь оставляет селектор пустым и вызываетAFT0009: дайте разрешённым классам общий интерфейс или базовый класс и укажите его.AFT0005теперь проверяет все типы атрибута вместе.- IMGUI-инспектор больше не проверяет список
[SerializeReference]на дубликаты целиком для каждого элемента на каждом GUI-событии: проверка идёт один раз на список за такт редактора или при изменении размера списка. Поле с общей ссылкой больше не создаётSerializedObjectна каждой перерисовке. - В инспекторе runtime-объекта селектор типов больше не предлагает типы из editor-only сборок (
UnityEditor, asmdef только для Editor и папкиEditor): плеер не может их найти, и в билде значение молча становилосьnullили потерянной ссылкой. Поля окон редактора и других editor-only объектов по-прежнему предлагают любые типы. - Селектор типов без ограничений (
SerializableTypeбезT,[TypeSelector]на строке,TypeField) переиспользует список типов между открытиями, а не собирает его заново из всех загруженных типов. SerializeReferenceIMGUIList.Drawтеперь бросаетArgumentNullExceptionдля свойстваnullиArgumentExceptionдля свойства, которое не является списком managed references, какSerializeReferenceEditorGUI.CreateList; раньше он ничего не рисовал. Меткаnullтеперь показывает отображаемое имя свойства; чтобы скрыть её, передайтеGUIContent.none.- Сгенерированный код
this.Marker()теперь объявляет поля маркеров только подENABLE_PROFILER, как и телоMarker(), которое их читает: сборки без профайлера больше не создают все маркеры в статическом конструкторе. ProfilerMarkerExtensionsForGenerator.Marker(this object)сталMarker<T>(this T, [CallerLineNumber] int line = -1): вызов в структуре, которую генератор не может обработать, больше не упаковывается, и Burst-джоба компилируется. Параметры у него те же, что у сгенерированной перегрузки, поэтому маркеры получает и тип без пространства имён, как в шаблоне скрипта Unity. Вызовthis.Marker()внутри дерева выражений больше не компилируется (CS0854), а группе методов теперь нуженFunc<int, AutoScope>.AFT0010теперь сообщает о любом вызовеthis.Marker(), который не открывает маркер, а не только о неподдерживаемых типах: получатель другого типа (other.Marker(), вызовы в статических классах), метод интерфейса по умолчанию, явный аргумент (this.Marker(5)) или аргумент типа,this?.Marker(), статическая форма вызова, группа методов и вызов внутри дерева выражений. Для таких вызовов генератор больше не создаёт мёртвые маркеры.- Generic-класс называет вложенные аргументы типа так, как их пишет C# (
Foo<List<Int32>>.Run (line),Foo<Outer<Int32>.Inner>.Run (line)вместоFoo<List`1>,Foo<Inner>). Generic-структура получает один маркер на точку вызова для всех закрытых типов с именемJob<T>.Execute (line), потому что Burst не может выполнить метку для каждого типа. - Сгенерированный
Marker()выбирает маркер по строке черезswitch, поэтому его стоимость больше не растёт с числом точек вызова в типе. - Сгенерированный
Marker()принимает структуру поin, поэтомуthis.Marker()в структуре, например в большой джобе, больше не копирует весь экземпляр при каждом вызове. Копия делалась в Mono (редактор, Mono-плееры) и в IL2CPP, когда вызов и перегрузка попадали в разные C++-файлы. - Окно Sample Themes подписывается на цикл обновления редактора, рендер камер и сохранение сцен только при включённом предпросмотре Light или Dark; в режиме по умолчанию Authored оно не добавляет редактору обработчиков.
Aspid.FastTools.VisualElements.Mathбольше не компилируется пустой сборкой в проектах безcom.unity.mathematics.- Анимированный фон из точек в окне FastTools и на странице настроек рисует все точки одним мешем, а не тесселирует отдельный путь на каждую точку в каждом кадре, и замирает, пока Unity в фоне, поэтому открытое окно без действий больше не нагружает редактор.
- Окно FastTools (Welcome, Asset References, Project References и Settings) и его страницы в Project Settings и Preferences учитывают светлую тему редактора: фон, карточки, текст, статусные цвета и окно выбора типа внутри него берут светлую палитру
Aspid-FastTools-Default-Light.uss; раньше они оставались тёмными в обеих темах. Theme override по-прежнему накладывается поверх любой из палитр. [TypeSelector]на поле-массиве илиList<T>теперь относится ко всей коллекции (applyToCollection): его drawer рисует список и выбор типа для каждого элемента.PropertyFieldиEditorGUILayout.PropertyFieldдля такого списка теперь получают + с выбором типа в UI Toolkit и IMGUI, аPropertyFieldдля отдельного элемента больше не показывает выбор типа.SerializeReferenceIMGUIList.DrawиSerializeReferenceEditorGUI.CreateListдобавляют кbaseTypesограничения[TypeSelector]с поля списка. Списки managed references, которые рисует пакет, теперь учитывают[NonReorderable].
Удалено
- Из расширений
SerializedPropertyудалёнSetExposedReferenceAndApply(); вызывайтеSetExposedReference(). Без контекстаIExposedPropertyTableсеттерexposedReferenceValueв Unity сам применяет запись и записывает Undo, поэтому дополнительное применение ничего не делало, а вариант без Undo поверх него построить нельзя. - Удалено editor-only свойство
SerializableMonoScript.Script, которое возвращало ассетMonoScript; публичного доступа к ассету больше нет. Тип по-прежнему доступен черезTypeили неявное преобразование вType. - Удалены
AddMakeItem/RemoveMakeItemуListViewиTreeView, а такжеAddMakeHeader/AddMakeFooter/AddMakeNoneElementуBaseListViewвместе с парамиRemove*; у списка одна фабрика, поэтому вызывайтеSetMakeItem,SetMakeHeader,SetMakeFooterилиSetMakeNoneElement. - Runtime-методы
Aspid.FastTools.StringExtensions.ToKebabCaseиAspid.FastTools.TypeExtensions.GetMembersInfosIncludingBaseClassesубраны из публичного API без замены.
Исправлено
- Значок
SHAREDв Asset References теперь вмещает свой текст; раньше он сжимался до ширины цветной точки, текст вылезал за его край, а точка закрывала букву «H». - Asset References показывает незаполненные обязательные поля (карточки Required type is not set и значки REQUIRED) ассета из папки Excluded scan folders, как уже показывал его потерянные типы; в Project References и проверки build / CI такой ассет по-прежнему не попадает.
GetDisplayName()иGetDisplayNameWithIndex()больше не добавляют « (Script)», когда[AddComponentMenu]унаследован от базового класса или его путь пуст либо заканчивается на/; такие типы получают «очеловеченное» имя типа. Заголовок теперь берётся из атрибута, объявленного на самом типе, а тип с[Obsolete]больше не получает « (Deprecated)».- Ссылка на член
[TypeSelector(nameof(...))]у поля внутри[Serializable]-класса или элемента списка теперь разрешается на экземпляре, который объявляет поле, — так её уже проверяют анализаторыAFT0006–AFT0008. Раньше член искался на инспектируемом компоненте или ассете, и инспектор показывал предупреждение. То же относится к селектору окна Asset References. AFT0007больше не ломает компиляцию на члене типаType?при#nullable enableи теперь сообщает о свойстве без getter, которое инспектор не может прочитать.AFT0004теперь сообщает и о полеUnityEngine.Object?.AFT0005больше не предупреждает о generic-типе поля или базовом типе (IState<Enemy>,Base<int>,typeof(IFoo<int>)), у которого есть закрытая или открытая generic-реализация, и о реализации черезout/in-вариантность — она больше не вызывает иAFT0003. Ни одно из них не срабатывает на поле типа generic-параметра (TвSlot<T>). Несвязанныйtypeof(Base<>)больше не вызываетAFT0003иAFT0005, если поле может заполнить открытая generic-реализация вродеImpl<T> : Base<T>.[field: TypeSelector]и[field: SerializeReference, TypeSelector]на автосвойстве теперь проверяются правиламиAFT0001–AFT0009, аAFT0003теперь проверяет и поляSerializableType<T>иSerializableMonoScript<T>.- Fix и Smart Fix отсутствующего типа в сохранённом ассете в инспекторе UI Toolkit больше не выводят исключение; поля ссылок в других инспекторах обновляются сразу после ремонта.
- В Edit Mode уведомление Shared reference, его номер и пункт Make Unique Reference теперь обновляются сразу после правки из IMGUI-инспектора, через Link to Existing или в окне графа ссылок; раньше они показывали состояние до правки, пока не сменится выделение.
- Вложенное поле
[SerializeReference]теперь сохраняет пользовательский drawer, зарегистрированный для его объявленного типа через открытый generic-тип (typeof(Effect<>)), базовый класс или интерфейс, даже безuseForChildren, а также drawer базового класса атрибута; раньше пакет рисовал поверх них свой заголовок и выбор типа. Во вложенном списке такой drawer рисует каждый элемент и в IMGUI, и в UI Toolkit, а + сохраняет выбор типа. Drawer только хранимого типа выбор типа не заменяет. - Сброс пользовательских настроек больше не перечисляет в подсказке и диалоге подтверждения удалённую опцию «Dropdown without [TypeSelector]».
ComponentTypeSelectorтеперь добавляет компоненты из[RequireComponent]нового класса и отменяет смену типа с предупреждением в Console, если она создала бы дубликат класса с[DisallowMultipleComponent], убрала класс, который нужен другому компоненту, или потребовала компонент, который нельзя добавить. Нужные компоненты добавляются раньше нового класса, поэтому егоOnValidateих уже находит. Раньше объект оставался без нужных компонентов или с дубликатами.- Create New Script… у поля
[SerializeReference]предлагаетNewInteractableдляIInteractable(былоNewnteractable) иNewEffectдляIEffect<T>или generic-базового класса (было недопустимоеNewEffect`1, которое отклонялось при подтверждении). - Сохранённый шаблон, тип которого сейчас не находится (другая ветка, удалённый пакет, класс перенесён в другой namespace или сборку), теперь только скрывается из Paste Template. Раньше открытие контекстного меню удаляло его навсегда, во всех копиях проекта. Paste Template → Remove Missing (N)… удаляет такие шаблоны по запросу, а перезапись такого шаблона по имени сообщает, что его тип не найден.
- Excluded scan folders принимает только
Assetsи папки внутри неё — только их обходят проектные сканирования. Папка изPackages/или другого места сохранялась, но ничего не исключала. - Поиск в селекторе типов больше не совпадает с частью имени, где указана сборка: короткие запросы вроде
Key,Token,verилиnullнаходили все типы. Поиск сравнивает подпись, имя типа и полное имя с пространством имён и внешними типами (Namespace.Outer.Name). - Ввод и Backspace в селекторе типов снова меняют запрос после перехода в результаты стрелкой вниз; раньше они пропадали, пока не щёлкнуть по полю поиска.
- Для потерянного типа селектор больше не выделяет
<None>, поэтому Enter сразу после открытия не стирает сохранённое имя. - В инспекторе UI Toolkit выбор
<None>теперь очищаетSerializableMonoScriptс потерянным типом; раньше поле продолжало показывать<Missing …>. - + у списка
[TypeSelector][SerializeReference], вложенного в элемент другого массива (список структур, список внутри элемента списка), теперь добавляет элемент в этот список; раньше он бросалInvalidOperationExceptionи ничего не добавлял. - + у массива, элементы которого содержат поле
[TypeSelector][SerializeReference](например,WeaponSlot[]в примере), теперь добавляет обычный элемент; раньше, если в массиве уже был элемент, он открывал селектор типа этого поля и бросал исключение. - + у списка managed references при выборе нескольких объектов теперь добавляет независимый экземпляр в каждый объект одной группой Undo. В IMGUI раньше менялся только первый объект, а в UI Toolkit новый элемент делил экземпляр с предыдущим.
- Инспектор
EnumValuesбольше не переписывает ключи при отрисовке: строка, ключ которой enum не может распознать (после смены enum вEnumValues<TValue>, переименования или удаления члена), показывается со своим ключом, например<Missing Frozen>, и сохраняет его, пока вы не выберете член. Раньше ей подставлялся первый член enum, и возврат прежнего типа строки не восстанавливал. Строка, добавленная в пустую таблицу, теперь показывается как<None>и пропускается с ошибкой, пока вы не выберете член; раньше ей автоматически подставлялся первый член. - Populate Missing Enum Members теперь работает, когда значение — массив или
List<T>; раньше пункт бросал исключение и оставлял недосозданную строку. Для enum с алиасами (Default = Medium) каждое значение добавляется один раз, а пункт становится неактивным, когда строки есть у всех значений; раньше каждое нажатие добавляло дубликат. - Строка
EnumValuesс[Flags]-enum наlongилиulong, а также наuintс членом в 31-м бите, получает выпадающий список флагов, который сохраняет все биты; для 64-битного enum IMGUI-инспектор раньше бросал исключение при каждой перерисовке, а UI Toolkit показывал неверную маску и записывал другой ключ. - В UI Toolkit-инспекторе выпадающий список ключа строки
EnumValuesтеперь следует за Undo, Revert и Paste, а заголовок таблицы показывает метку, переданную вPropertyField, а не всегда имя поля. - Undo после Fix отсутствующего типа в открытой сцене или Prefab Mode возвращает отсутствующую ссылку вместе с сохранёнными данными; раньше поле оставалось пустым, а следующее сохранение записывало
rid: -2. Заменённая запись теперь удаляется при сохранении сцены или префаба (Auto Save в Prefab Mode сохраняет сразу после Fix), поэтому предупреждение Unity об отсутствующих типах остаётся до сохранения; это сохранение также очищает историю Undo объекта, поэтому восстановление уже не отменить. - Editor-сборка пакета теперь компилируется в Unity 6000.5, где
Object.GetInstanceID()стал ошибкой (CS0619); раньше проект оставался в Safe Mode, и ни один editor-инструмент пакета не работал. - Поля в обычном инспекторе, UI Toolkit или IMGUI, теперь учитывают светлую тему редактора: drawer
EnumValuesберёт фон из темы Unity, уведомления о ссылках и подпись пропавшего типа у полей[SerializeReference]— цвет предупреждения Unity, а иконки предупреждения, информации и папки — варианты для светлой темы. - Окно выбора типа читается в светлой теме редактора: открытое из поля инспектора, оно берёт светлую палитру и светлые иконки папок, Favorites и Recent; раньше светлый текст тёмной палитры рисовался на светлом фоне всплывающего окна Unity.
- Вкладка Welcome окна FastTools тоже учитывает theme override; раньше она оставалась во встроенной палитре.
- Theme override теперь перекрашивает карточки, панели, статусные заливки, полосы прокрутки, фон из точек и переключатели окон Aspid: их цвета вынесены в токены
--aspid-colors-*, а переключатели читают необязательные токены--aspid-colors-switch-*. - На Unity 6000.0–6000.2 поле
[SerializeReference], пикер и окна Project References и Asset References снова получают стили: два листа стилей использовали запись цвета, которую эти версии не разбирают, поэтому каждый отбрасывался целиком, а при импорте в Console появлялась ошибка. - Кнопки и foldout'ы внутри поля
[SerializeReference], нарисованного на UI Toolkit, сохраняют свой вид: кнопка пользовательского drawer'а или+/−вложенного списка больше не сжимается до 18×18 с иконкой папки, а вложенный foldout больше не перенимает раскладку заголовка поля. - Fix, Fix all и Undo в сводке больше не переписывают тип исправной managed-ссылки, если на сломанную указывает
[SerializeReference]-список внутри другой ссылки (родитель со списком детей). Inspector читает у таких ссылок правильный сохранённый тип и поля, а граф Project References больше не показывает фантомные узлы, чей Clear удалял исправные entry. - Защита missing-списков теперь сохраняет снимок missing-элемента, на который указывает ещё и список другой ссылки, и восстанавливает его в собственный список объекта, а не в одноимённый список, вложенный в другое поле.
- Защита missing-списков больше не возвращает missing-элемент списка, который вы удалили или сделали
<None>и сохранили; если удалён другой элемент, она восстанавливает missing-элементы по их новым индексам. Если удалённый элемент стоял среди других missing- или<None>-элементов, по сохранённому файлу не понять, какой именно: защита оставляет<None>-элементы и первые missing-элементы, а последний missing-элемент не восстанавливает. Загруженные сцены и префабы, сохранённые из Prefab Mode, больше не защищаются: защита не переписывает их файлы и не восстанавливает их missing-элементы списков. - Элемент списка, восстановленный защитой missing-списков, сохраняет исходный id ссылки, если он свободен, а иначе получает случайный. Раньше он брал следующий id после максимального в файле, который часто уже занимал override в варианте, вложенном префабе или сцене: такой override терял свой тип и делил данные с восстановленным элементом.
- Объекты с отрицательным fileID (компоненты префабов, под-ассеты) теперь читаются как отдельные документы: их missing-ссылки попадают в сканы и build gate, незаполненные required-поля — в сканы, а Fix, Clear и удаление orphan больше не правят и не удаляют entry соседнего объекта.
- Поле
[SerializeReference]в варианте префаба, вложенном префабе или экземпляре в сцене с потерянным типом теперь показывает Missing type вместо пустого<None>; подсказка называет исходный префаб, где нужно чинить тип, или сообщает, что тип хранится в override префаба. Обязательное поле с таким потерянным типом больше не считается незаданным в-srGateRequiredи окнах References. - Уведомление о поломке больше не ждёт, пока Project References просканирует проект в этой сессии: базовую линию задаёт фоновое чтение файлов ассетов в начале сессии, а ассеты, сохранённые позже, её обновляют, поэтому тип, впервые назначенный в этой сессии, тоже отслеживается. О типе, сломавшемся до окончания этого чтения, уведомление не появляется.
- Удаление скрипта, в котором объявлены только компоненты или ScriptableObject, больше не сканирует все ассеты проекта; для остальных скриптов при долгой проверке появляется прогресс-бар, и кнопка отмены в нём отменяет удаление.
- Защита удаления теперь предупреждает обо всех типах, объявленных в скрипте, в том числе в файле без класса с его именем (
PistolиRifleвWeapons.cs) и о вложенных типах (Outer.Inner); раньше проверялся только класс с именем файла.partial-тип учитывается, только если ни один оставшийся скрипт не объявляет другую его часть. - Сканы SerializeReference пропускают двоичные ассеты и указатели Git LFS по первым байтам файла, а не декодируют каждый файл как текст при каждой сборке. Build gate и проверка в CI предупреждают, если файлы остались непроверенными (любой двоичный файл вне режима Force Text, двоичный префаб, сцена или ScriptableObject в режиме Force Text, нескачанный указатель), а отчёт CI считает и перечисляет такие файлы; раньше такой проект проходил с 0 нарушений.
- Массив или список с
[TypeSelector(Required = true)]на сцене больше не считается незаполненным в-srGateRequiredи Project References: как и обещает документация, коллекции на сценах не проверяются. - Project References больше не пишет «Project clean» и «Nothing left to repair», пока required-поля не проверены (до первого Scan Project, после очистки в Prefab Mode либо в открытой сцене или при gate severity Off), а объясняет, почему они не проверены, и предлагает Rescan. После очистки ссылок на диске заново проверяются изменённые файлы, а также варианты и префабы, вкладывающие изменённый префаб, поэтому их required-нарушения остаются в списке, а заголовок предупреждает о них.
- Проверка required-полей в
-srGateRequiredи Scan Project теперь выгружает загруженные префабы и ассеты, поэтому её память больше не растёт с размером проекта. - Assign Required для поля
SerializableMonoScriptв Asset References теперь предлагает только типы со скриптом, как и Inspector; раньше можно было выбрать вложенный, generic-тип или тип из DLL, и ссылка на скрипт терялась. - Незаданное обязательное поле
SerializableType,SerializableType<T>илиSerializableMonoScriptв префабе или ScriptableObject теперь указывается в-srGateRequired, CI-отчёте и окнах References по своему пути (weaponType), как на сцене; раньше путь оканчивался на._assemblyQualifiedName. - В редакторе
SerializableMonoScriptтеперь берёт тип из своего скрипта, если сохранённое имя больше не находится. Объект, загруженный в Play Mode после переименования класса (дополнительная сцена,Resources.Load, вход в Play Mode без перезагрузки домена и сцены), больше не получаетnull, пока его ассет не пересохранён. SerializableTypeиSerializableMonoScriptтеперь кешируют и неудачный поиск: чтение.Typeу потерянного типа больше не вызываетType.GetTypeкаждый раз, а кеш сбрасывается при смене сохранённого имени.- Исправление пропавшего типа
[SerializeReference](смена типа, очистка, удаление осиротевшей записи, восстановление элемента списка) теперь сначала делает checkout ассета в системе контроля версий, как это делают сохранения самого Unity. Ассет только для чтения остаётся нетронутым с понятной ошибкой вместо исключения доступа, правка заменяет файл за один шаг, поэтому сбой записи больше не оставляет его обрезанным, а BOM UTF-8 сохраняется. - Восстановление потерянного типа больше не отбрасывает молча несохранённые изменения восстанавливаемого ассета. Fix и Smart Fix в инспекторе, а также восстановление и очистка в Asset References предлагают сначала сохранить такой ассет; Fix all, Clear и Undo в Project References пропускают его или очищают в памяти. Fix в инспекторе больше не переписывает префаб, открытый в Prefab Mode.
- Итоги в Project References вместе с их Undo теперь переживают переход на другую вкладку окна, в том числе переход в Asset References по строке записи; раньше они пропадали вместе с вкладкой. Rescan, закрытие окна или перезагрузка домена по-прежнему очищают их.
this.Marker()внутри вложенного типаprivateилиprotectedбольше не ломает компиляцию ошибкой CS0122. Сгенерированная перегрузка не видит такой тип, поэтому генератор теперь его пропускает: вызов компилируется, маркер не открывается, аAFT0010сообщает об этом — чтобы профилировать тип, сделайте егоinternalилиpublic.this.Marker()в типе, вложенном в generic-тип (Outer<T>.Inner), теперь компилируется; раньше сгенерированной перегрузке не хватало параметров внешнего типа (CS0246).this.Marker()в аксессоре индексатора и в статическом конструкторе теперь компилируется; раньше имена сгенерированных полей были недопустимыми. Маркеры называютсяType.Indexer (line)иType.StaticCtor (line).this.Marker()в аксессоре события теперь называется по имени события, как в аксессоре свойства:Type.Changed (line)вместоType.add_Changed (line)/Type.remove_Changed (line), в том числе в явной реализации интерфейса.this.Marker()больше не ломает компиляцию в инициализаторе авто-свойства, в статическом классе и в методе интерфейса по умолчанию, в пространстве имён или параметре типа с именем-ключевым словом (Game.@event,Foo<@event>), а также когда имена типов различаются только регистром или сводятся к одному имени (Foo/foo,Foo<T>/Foo_1,Outer.Inner/Outer_Inner); в части этих случаев пропадали все маркеры сборки.this.Marker()в типе с[Obsolete], во вложенном в него типе и в generic-типе с таким ограничением больше не вызывает CS0618 в сгенерированном коде, а в типе с[Obsolete(..., true)]больше не ломает компиляцию ошибкой CS0619.Foo,Foo<T>иFoo<T1, T2>в одном пространстве имён больше не делят один сгенерированный класс, в котором маркеры получал только первый тип; маркеры собственногоEnumValues<TEnum, TValue>пакета теперь открываются.- Вызов
this.Marker(), разбитый на несколько строк или стоящий под директивой#line, теперь открывает свой маркер; генератор брал не ту строку, что[CallerLineNumber]. - Generic-структура с
[BurstCompile]больше не ломает сборку Burst (BC1025/BC1360). - Тип, унаследованный от типа другой сборки, с которой он делит пространство имён через
InternalsVisibleTo, теперь получает собственные маркеры; раньше его вызовы попадали в перегрузку базового типа и ничего не открывали. WithName($"Br{{ace}}")даётBr{ace}, текстWithNameс U+2028, U+2029 или U+0085 компилируется, а собственное расширениеWithNameпользователя больше не переименовывает маркер.Persistent()больше не оставляет неосвобождённым созданныйSerializedObject, если путь свойства больше не существует на целевых объектах: он освобождается перед возвратомnull.AddChildren,InsertChildrenи их варианты…IfсIEnumerableбольше не бросаютInvalidOperationException(«Collection was modified»), когда получаютChildren()другого элемента:target.AddChildren(source.Children())переносит всех детей.- Пример Types: селектор
Enemy Typeбольше не предлагает абстрактныйEnemy, из-за которого появлялись пустые капсулы и ошибка на каждого врага; шаг README с переименованием теперь использует Rename-рефакторинг IDE, иArmoredGruntпродолжает компилироваться. - Пример SerializeReferences: при импорте больше нет предупреждения CS0414, а удаление Training Dummy в Play Mode больше не бросает
MissingReferenceExceptionна каждом выстреле. - Пример EditorTools: окно Ability Catalog отслеживает ассеты, созданные или удалённые в окне Project, а Create выделяет новый ассет и при активном поиске.
- Примеры EnumValues и ProfilerMarkers больше не ломают компиляцию проекта без встроенного модуля Physics: там их скрипты пропускаются, а в описаниях примеров сказано, что модуль нужен.
- Примеры больше не импортируют как текстуры десять неиспользуемых скриншотов (около 1 МБ).
Persistent()сохраняетcontextисходногоSerializedObject, поэтомуExposedReference, прочитанный или записанный через копию, разрешается в той же таблице (например,PlayableDirector), а не в значении по умолчанию в ассете.- Link to Existing в контекстном меню
[SerializeReference]теперь предлагает только экземпляры, которые принимает выбор типа поля с учётом базовых типов[TypeSelector], в том числе заданных ссылкой на член; раньше он предлагал любой экземпляр, совместимый с объявленным типом поля. - Find Usages в контекстном меню
[SerializeReference]теперь находит использования именно того типа, что лежит в поле (с учётом пространства имён и сборки); раньше в результаты попадало любое хранимое имя класса, содержащее его имя, напримерPistolMk2илиPistolиз другого пространства имён. Запросsr:, набранный вручную, по-прежнему ищет по подстроке имени класса. - Find Usages of … и Link to Existing в контекстном меню
[SerializeReference]называют generic-тип так же, как выбор типа:Modifier<Single>или имя из[TypeSelectorDisplay]; раньше там былоModifier`1. Символ/в отображаемом имени больше не открывает подменю. - В стандартном UI Toolkit Inspector + пустого списка
[TypeSelector][SerializeReference]теперь открывает выбор типа; раньше он добавлял элемент<None>, а выбор типа появлялся, только когда в списке уже был элемент. - Уведомление о поломке ссылок и настройка детектора поломок указывают на Project References, а не на старое имя вкладки — Repair.
1.0.0-rc.8 — 2026-09-06
Первый релиз. Unity 6000.0, сборки Aspid.FastTools / Aspid.FastTools.Editor, предсобранные Roslyn-DLL Aspid.FastTools.Generators / Aspid.FastTools.Analyzers. Все инспекторные возможности работают и в IMGUI, и в UI Toolkit.
Добавлено
Serializable Type System
SerializableType/SerializableType<T>—[Serializable]-обёртка надSystem.Type, ленивое разрешение, неявное приведение кType, конструктор сType,AssemblyQualifiedName.SerializableMonoScript/SerializableMonoScript<T>— то же, но через ассет скрипта, поэтому переименование и перенос класса ничего не ломают; плеер сериализует одно имя.SerializableTypeBaseиISerializableTypeдля полиморфной работы с любой обёрткой.[TypeSelector]— иерархический пикер типов на поляхstring,SerializableType/SerializableMonoScriptи[SerializeReference], а также на массивах и списках из них. Ограничения базовыми типами,Allow(TypeAllow),Required, ссылки на члены в строковых аргументах (Type,string,SerializableType, массивы из них, разрешаются вживую).[TypeSelectorDisplay]—Name,Group,Tooltip,Icon,Hiddenдля строки типа в пикере.ComponentTypeSelector— заменяет соседнийComponentна месте через дропдаун типов.TypeSelectorWindowс публичным APIShow(...): дерево пространств имён, поиск, навигация с клавиатуры, Favorites и Recent,TypeSelectorFilter(Predicate,AdditionalTypes,HideNoneOption).- UI Toolkit-элементы
TypeField/InspectorTypeField, на которых построены drawer'ы.
SerializeReference Selector
- Дропдаун типов на полях
[SerializeReference], включая вложенные ссылки (до 8 уровней); кастомные drawer'ы и[Header]/[Space]/[Tooltip]учитываются. - Открытые generic-реализации: аргументы выводятся из аргументов типа поля и его интерфейсов, иначе собираются на второй странице пикера.
- Перенос данных при смене типа, Copy / Paste, мультиредактирование, развязывание дубликатов.
- Уведомления об общих ссылках с Make unique, цветными группами и переходом к участникам.
- Назначение перетаскиванием
MonoScript, именованные шаблоны, Link to Existing,+списка через пикер, Create New Script…, Find Usages.
Починка потерянных ссылок
- Встроенный Fix на потерянном типе с сохранением данных; работает для сохранённых ассетов, Prefab Mode и объектов сцены.
- Smart Fix ранжирует вероятную замену (
[MovedFrom], то же имя в другом месте, регистр, совпадение формы полей). - Переименования
[MovedFrom]показываются как ожидающие миграции с Migrate all в один клик и не считаются нарушениями. - Уведомление о поломке после переименования / удаления скрипта или реимпорта; защита удаления скриптов, используемых как managed reference; предпросмотр YAML-diff перед каждой массовой перезаписью.
Рабочее окно (Tools → Aspid 🐍 → FastTools)
- Welcome — примеры с отметками установки; открывается автоматически один раз на версию пакета.
- Asset References — весь граф
[SerializeReference]ассета из YAML с предупреждающей полосой на отсутствующих типах и бейджамиSHARED, встроенным Fix, Clear для осиротевших записей, Open Source Prefab. - Project References —
Scan ProjectпоAssets/, Fix all на тип с Undo, Smart Fix, Migrate all, Required violations. - Settings — все настройки пакета с полосками области (общая / пользовательская) и сбросом по областям.
- Навигация с клавиатуры, легенды, контекстные меню строк на каждой вкладке.
- Проектный индекс использований, провайдер Quick Search
sr:. - Build / CI gate:
IPreprocessBuildWithReportплюс headlessSerializeReferenceCiGate.RunCheckс-srGateReport,-srGateRequired,-srGateWarnOnly,-srGateFail; строгостьOff/Warn/Failи исключённые папки в коммитимомProjectSettings/SerializeReferenceSharedSettings.asset.
Настройки
- Project Settings → Aspid.FastTools → SerializeReference — авторазвязывание, обнаружение поломок, строгость gate, исключённые папки.
- Preferences → Aspid.FastTools — зеркало вкладки Settings: References, Type Selector (Favorites, ёмкость Recent), Welcome, тема.
Диагностики анализатора
AFT0001(ошибка) —[TypeSelector]на неподдерживаемом поле.AFT0002(предупреждение) —Allowна managed reference игнорируется.AFT0003(предупреждение) — базовый тип не имеет общих конкретных типов с полем.AFT0004(ошибка) —[SerializeReference]на типеUnityEngine.Object.AFT0005(предупреждение) — ни один конкретный сериализуемый тип не удовлетворяет ограничениям.AFT0006(ошибка) — строковый аргумент не является ни членом, ни именем типа.AFT0007(ошибка) — указанный член не может задавать базовые типы.AFT0008(предупреждение) — строка-не-идентификатор не является корректным именем типа.
ProfilerMarkers
this.Marker()—ProfilerMarker, уникальный для места вызова.ProfilerMarkersGenerator— создаёт по полю маркера на место вызова; поддерживает лямбды, локальные функции,.WithName(...)и имена$"..."; вырезается безENABLE_PROFILER.
EnumValues
EnumValues<TValue>— сериализуемый словарь с ключом-enum, значением по умолчанию и поддержкой[Flags].EnumValues<TEnum, TValue>— типизированный вариант, поиск без боксинга, структурный перечислитель.- Drawer'ы с редактированием на месте и Populate Missing Enum Members.
Fluent-расширения VisualElement
- Fluent API на
VisualElement: раскладка, стиль, границы, цвета, переходы, колбэки, USS, управление детьми с вариантами*If, пресеты стилей. - Помощники для
Button,BaseField<T>(SetLabelдля 29 типов),Focusable,Foldout,HelpBox,Image,IMGUIContainer,IMixedValueSupport,INotifyValueChanged,IStyle,ICustomStyle, list view,Manipulators,ProgressBar,Slider,TextElement. - Редактор:
BindTo/UnbindFrom,BindPropertyTo,SetBindingPath,SetLabelдляPropertyField,AddOpenScriptCommand,GetOwnerWindow. Aspid.FastTools.VisualElements.Math—SetValue/ValueChangedдля типовUnity.Mathematics, компилируется только сcom.unity.mathematics.
Расширения SerializedProperty
- Типизированные сеттеры
Set*/Set*AndApply,Update,ApplyModifiedProperties,Persistent, помощники путей,GetPropertyType/GetFieldInfo/GetDeclaringInstance.
Редакторские помощники
GetScriptName()/GetScriptNameWithIndex().- Команда открытия скрипта, понимающая интерфейсы в файлах с другим именем и вложенные типы.
Примеры
- Types, SerializeReferences, EnumValues, ProfilerMarkers, EditorTools — по одной работающей сцене (или окну) с
README.md.
Документация и инструменты
- Документация на английском и русском в
Documentation/, публикуется на https://vpdpersonal.github.io/Aspid.FastTools/. - Плагин
aspid-fasttoolsдля Claude Code в Aspid.Claude.Plugins. upm/upm/<version>для стабильных релизов,upm-previewдля предрелизов. До первого стабильного релиза в веткеupmостаётся старый пакетcom.aspid.fasttools(1.0.0-rc.2).- EditMode-тесты для YAML-редактора и сканирования CI gate.