Перейти к содержимому

Создать генератор встроенных объектов

Создать параметрический генератор из встроенных объектов BDEngine.

Создадим ряд каменных Block Display с заданным количеством и шагом. Результат состоит из обычных встроенных объектов: их можно редактировать и сохранять вместе с проектом.

Нужно уметь установить и запустить плагин. Начните с пустого тестового проекта в обычном режиме моделирования.

Что генерируем

Скачать полный плагин generate.js. После установки и перезапуска в меню дока появится «Создать ряд каменных дисплеев». По умолчанию плагин создаёт 5 каменных блоков с шагом 1.25 вдоль мировой X, начиная от точки (0, 0, 0).

Генератор добавляет объекты в корень текущего проекта. Он не использует выделенную группу как неявного родителя и не меняет уже существующие объекты. Повторный запуск добавляет новый ряд в тех же координатах, поэтому ряды могут совпасть визуально.

Пример работает в режиме моделирования вне совместной сессии. Вызовы добавления идут через editorAPI; проверки режима, корня проекта и поколения истории используют внутренний editor. Это явно ограниченная зависимость от реализации редактора, а не дополнительный стабильный контракт editorAPI.

Параметры и валидация

Перед созданием объектов проверяются:

Параметр Правило примера
Количество Целое число от 1 до 24.
Шаг Конечное число от 1 до 16, в блоках.
Блок stone, найденный в editorAPI.getBlockList().

Числовые ограничения выбраны, чтобы случайный ввод не создал огромную сцену. Они не являются лимитами редактора. Отмена любого диалога завершает запуск без изменений. Пустая строка проверяется отдельно: Number('') равен нулю и сам по себе не распознаёт пустой ввод.

Если расширяете генератор до выбора блока, берите допустимые идентификаторы из getBlockList() и проверяйте выбор до начала генерации. Список содержит строки состояний блоков; не конструируйте неизвестное состояние только по введённому названию.

Асинхронное добавление объектов

Каждый вызов add нужно дождаться:

const object = await editorAPI.add(
'stone',
'BlockDisplay',
root,
true,
new window.THREE.Vector3(index * gap, 0, 0)
);
if (!object) throw new Error('Дисплей не создан.');

Здесь root - сохранённый корень текущего проекта, index - номер элемента с нуля, gap - проверенный шаг. Глобальный THREE предоставляется средой плагинов.

add может вернуть объект, false или undefined: отсутствие исключения ещё не означает успех. Например, создание может быть отклонено в неподходящем режиме или прервано сменой проекта. Цикл в полном примере последовательно выполняет await, проверяет результат и только затем создаёт следующий элемент.

Не используйте array.forEach(async ...), рассчитывая дождаться завершения всего ряда. Для последовательного добавления подходит обычный for. Флаг busy защищает от повторного запуска самого генератора, но не запрещает пользователю выполнять другие действия редактора.

Аргумент save: true разрешает запись команды добавления в историю. noReply оставлен равным false: в текущей реализации история добавляется только при save && !noReply. Поэтому noReply: true нельзя использовать как безобидный способ скрыть загрузку. Подробности: контракт add.

Трансформации и группировка

objPos должен быть THREE.Vector3, а не массив или простой объект {x, y, z}. При добавлении редактор преобразует мировую позицию в систему координат родителя. Для ряда используется обычный каменный блок без дополнительных смещений.

Положение передаётся сразу при создании. Так повторное выполнение команды добавления использует тот же параметр, вместо отдельного изменения позиции после записи истории. Не подменяйте встроенный объект произвольным THREE.Mesh: визуальная сетка сама по себе не становится Block Display и не получает его сохранение и Minecraft-экспорт.

Если после создания нужно изменить объект, у поддерживаемых типов есть setPosition, setRotation и setScale. Позиция задаётся в локальных координатах, вращение этими методами - в градусах. Такое отдельное изменение требует собственного решения для истории. См. трансформации встроенных и собственных объектов.

Пример не создаёт группу программно: Collection не является поддерживаемым типом add. После проверки выделите созданные дисплеи в дереве и сгруппируйте штатным действием редактора. Это обычная группа с обычными дисплеями, без специального объекта генератора.

Повтор и частичная ошибка

Асинхронная загрузка модели может завершиться уже после смены проекта. Полный пример запоминает корень, объект истории и его поколение, затем проверяет их перед каждым вызовом add и после его завершения. При несовпадении генерация останавливается. Проверки внутренних полей следует пересматривать при обновлении редактора.

Если успели добавиться несколько дисплеев, они не становятся автоматически одной транзакцией. Плагин показывает число созданных объектов. Пока проект и режим остались прежними, он предлагает удалить только созданные этим запуском дисплеи. Перед удалением проверяет, что объекты ещё находятся в текущем проекте, и не передаёт пустой массив в delete.

Каждый успешный add создаёт отдельный шаг истории. Очистка через delete добавляет ещё один шаг. Нельзя обещать, что одно Ctrl+Z отменит весь ряд или что после частичной ошибки история вернётся в исходное состояние. Если проект изменился, плагин не удаляет объекты в новом проекте.

Проверьте в редакторе:

  1. Количество 1, затем 5. В дереве должно появиться ровно соответствующее число новых Block Display.
  2. Координаты X при шаге 1.25: 0, 1.25, 2.5, 3.75, 5. Y и Z равны нулю.
  3. Отмену диалога, пустой ввод, дробное количество и слишком большие значения. До исправления параметров новых объектов быть не должно.
  4. Быстрое повторное нажатие пункта. Один запуск должен закончиться до следующего.
  5. Последовательную отмену и повтор команд истории: отменяется по одному добавлению, положение при повторе должно сохраниться.
  6. Сохранение, повторное открытие проекта и обычный экспорт небольшой модели.

Сценарии медленной загрузки, смены проекта и недоступного ресурса требуют отдельной проверки в редакторе. Синтаксическая проверка JS не подтверждает рендеринг и игровой экспорт результата.

Повторное использование

После группировки дайте группе понятное имя. Её можно использовать как заготовку в других проектах без установленного генератора: созданные дисплеи уже являются данными проекта. Параметры количества и шага плагин в группу не записывает, поэтому последующее изменение ряда выполняется обычными инструментами либо новым запуском генератора.

Дальше: сохранить сгенерированную заготовку как ассет.