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

Получить данные проекта и JSON-экспорт

Выбрать правильный вид данных: проект для слияния, геометрию или JSON игрового экспорта.

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

Скачать полный пример project-data.js. После установки на панели инструментов появится кнопка с иконкой JSON. Она открывает окно с тремя действиями. Пока выполняется одно из них, остальные кнопки и поля заблокированы. Проверяйте импорт на копии проекта.

Три разные задачи

Задача Что использовать Что получается
Добавить объекты из другого проекта и продолжить редактирование mergeContent(content, decode) Объекты добавляются в текущую сцену
Передать видимую геометрию собственному анализатору или экспортёру getMeshes() Временные THREE.Mesh со снимком геометрии
Получить данные для создания модели и воспроизведения анимаций в Minecraft await exportToJSON(fullProject, version) Объект игрового экспорта либо false при отказе

У editorAPI нет универсального метода getProject(), который возвращает всё редактируемое состояние. Для слияния используйте файл проекта или его исходную JSON-строку. Сериализация снимка мешей и JSON игрового экспорта не создают файл проекта BDEngine.

Слияние проекта, чтение мешей и экспорт выполняются через editorAPI. Внутренний window.editor используется для проверки текущего проекта перед импортом и получения выбранного индекса версии Minecraft. Публичного getter выбранной версии сейчас нет. Эти зависимости от внутреннего интерфейса нужно проверять после обновлений редактора.

Добавить содержимое проекта

Передайте файл .bdengine или .bdstudio как ArrayBuffer с decode: true. Чтение файла асинхронное: запомните исходный проект до arrayBuffer() и проверьте, что он не изменился, прежде чем вызывать импорт:

async function mergeProjectFile(file) {
// Внутренний editor: проверяйте эти поля при обновлении редактора.
const editor = window.editor;
const api = window.editorAPI;
if (!editor?.objects || !editor.history) {
throw new Error('Проект ещё не готов.');
}
const root = editor.objects;
const history = editor.history;
const historyGeneration = history._generation;
const loadGeneration = editor._projectLoadGeneration;
const content = await file.arrayBuffer();
if (
window.editor !== editor ||
editor.objects !== root ||
editor.history !== history ||
history._generation !== historyGeneration ||
editor._projectLoadGeneration !== loadGeneration
) {
throw new Error('Во время чтения файла проект изменился. Повторите импорт.');
}
await api.mergeContent(content, true);
}

file здесь - выбранный пользователем File из input[type=file]. Проверка учитывает замену редактора, корня проекта, истории и начало новой загрузки. Если исходный проект изменился, пример не вызывает mergeContent: повторите действие уже в нужном проекте. После начала слияния редактор выполняет собственные проверки актуальности проекта.

Закрытие окна не отменяет запущенную операцию. В полном примере состояние task общее для всех открытий окна и сохраняется при ручном повторном запуске скрипта. Если открыть окно заново во время чтения или импорта, его элементы останутся заблокированы до завершения операции. Новый запуск не начнёт второй импорт параллельно; результат появится в текущем окне.

Редактор сам распознаёт поддерживаемый контейнер проекта и его ресурсы. Не распаковывайте современный файл как произвольный ZIP и не отбрасывайте вложенные ресурсы. Для уже распакованной строки JSON проекта используйте decode: false:

await window.editorAPI.mergeContent(projectJsonText, false);

Это именно строка в формате проекта, а не объект, полученный через JSON.parse. JSON Server API не подходит: у него другой состав и другое назначение.

Метод добавляет содержимое к текущей сцене. В текущей реализации импортируемые структурные блоки имеют ограничения, о которых сообщает редактор. Обработанные ошибки также выводятся в интерфейсе. Обёртка editorAPI.mergeContent() не возвращает логический результат внутреннего метода, поэтому undefined после await нельзя считать ни признаком успеха, ни признаком ошибки. Проверяйте сцену и уведомления.

Точные входы описаны в справке mergeContent.

Получить временную геометрию

getMeshes() возвращает снимок видимых мешей. Инстансы менеджера мешей разворачиваются в отдельные Mesh; bounding boxes, light gizmos и меши внутри источников света пропускаются. Это не дерево объектов редактора: количество мешей не обязано совпадать с количеством строк в списке объектов.

const meshes = window.editorAPI.getMeshes();
try {
console.log('Мешей в снимке:', meshes.length);
// Читайте meshes здесь. Не добавляйте их обратно в проект для его копирования.
} finally {
for (const mesh of meshes) {
mesh.removeFromParent();
mesh.geometry.dispose();
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
materials.forEach(material => material.dispose());
}
}

В текущей реализации геометрии и материалы клонируются для снимка. Текстуры материалов могут оставаться общими с редактором: не вызывайте dispose() у map, alphaMap и других текстур снимка. Код выше освобождает только созданные для снимка геометрии и материалы после использования.

Мировая трансформация уже скопирована в mesh.matrix, а matrixAutoUpdate выключен. Не воспринимайте значения position, rotation и scale этих мешей как исходные редактируемые трансформации проекта. После изменения сцены запросите новый снимок. Подробности: контракт getMeshes.

Получить экспортный JSON

Укажите режим и индекс целевой версии Minecraft:

// Чтение внутренней настройки editor: проверяйте при обновлении редактора.
const version = window.editor.settingsEditor.exportMine.commandVersion;
const data = await window.editorAPI.exportToJSON(false, version);
if (data === false) {
console.log('Экспорт не получен. Посмотрите сообщение редактора.');
} else {
console.log(data.version, data.type);
}
  • fullProject: true запрашивает экспорт через Animator и при необходимости переводит редактор в этот режим. false не переключает уже открытый Animator обратно в режим модели. Поэтому результат зависит также от текущего режима: в Animator даже при false можно получить type: "full". Для модели сначала перейдите в режим редактирования модели. Это не обещание всех возможностей обычного датапака.
  • version - числовой индекс списка версий редактора, не строка "1.21.4" и не версия схемы JSON. Если аргумент пропущен, API выбирает последний поддерживаемый индекс, даже если пользователь до этого выбрал другую версию.
  • Метод меняет тип и выбранную версию в окне экспорта, обновляет его и показывает пользователю. Это не фоновый getter без побочных эффектов.
  • Ожидайте завершения через await; проверяйте false и обрабатывайте исключения. Например, незавершённые HeadPaint-текстуры блокируют экспорт.

Полный файл примера читает выбранный индекс при каждом нажатии кнопки, сохраняет возвращённый объект в bde-export.json и не отправляет его на сервер. Публикация не выполняется, временный ID не создаётся.

В возвращённом объекте поля version, type, passengers, datapack и meta находятся в корне, если присутствуют в данном экспорте. Оболочки content нет, а маркер [BDESERVERTAG] остаётся в строках. Не добавляйте HTTP-оболочку и не считайте эти данные редактируемым проектом.

Сигнатура: exportToJSON. Формат результата: структура JSON и различия источников.

Проверить на контрольной сцене

  1. Сохраните исходную работу. Создайте отдельный проект с одним block display.
  2. Откройте окно примера и посчитайте меши. После повторного нажатия сцена не должна получать новые объекты; счётчик показывает временную геометрию.
  3. Добавьте небольшой сохранённый проект через выбор файла. Проверьте добавленные объекты и уведомления, затем отмените именно импорт штатной историей редактора.
  4. Во время чтения файла переключите проект. Импорт должен отмениться с сообщением; объекты из файла не должны добавиться в новый проект.
  5. Во время операции закройте окно примера и откройте снова. Кнопки и поля должны оставаться заблокированными до завершения. Проверьте это и при ручном повторном запуске скрипта: после завершения новый экземпляр окна получает результат и снова разрешает действия.
  6. Перейдите в режим редактирования модели и выберите нужную версию Minecraft в окне экспорта. Скачайте JSON примера без флажка fullProject и сверьте version и type.
  7. В отдельной сцене добавьте анимацию и повторите с флажком. Проверяйте наличие данных по составу сцены, не требуйте все необязательные поля одновременно.

Реальные структурные блоки, раздельные начала координат групп и другие возможности обычного датапака не становятся доступными только из-за вызова API плагина. Перед разработкой потребителя прочитайте ограничения игрового JSON-экспорта.

Контракты примера сверены с publicFunctions.js, editor.js, utils.js, RenderRT.js, RenderRTCore.js, command.js и Export.js. Это сверка реализации; игровое исполнение произвольного экспортированного проекта требует отдельной проверки вашей интеграции.