Как загружать 3D-контент во время выполнения в сценарии AR с помощью xr-frame
В этой статье подробно объясняется механизм разделения загрузки ресурсов и подключения узлов в xr-frame. С помощью динамического скрипта обеспечивается гибкое подключение 3D-контента под узлом Block для реализации AR.
Официальные материалы
- Руководство по разработке xr-frame: Документация по движку XR от WeChat.
- Официальные примеры xr-frame: Включает базовые и продвинутые примеры использования.
Официальные материалы уже содержат достаточно информации о том, как загружать 3D-контент во время выполнения. В этой статье кратко описаны распространённые методы загрузки в сценариях AR.
Загрузка ресурсов vs Подключение узлов
В xr-frame отображение 3D-модели разделено на два этапа:
Загрузка ресурсов: Загрузка и парсинг файла модели (например,
.glb) из сети или локально в память. Модель готова, но не видна в сцене.Подключение узлов: Создание узла в дереве сцены и связывание загруженного ресурса с этим узлом. Только тогда модель появится на холсте отрисовки.
Как динамически загружать 3D-контент с помощью кода
Загрузка ресурсов
Вызов loadAsset через систему управления ресурсами сцены xr-frame для ручной загрузки ресурсов.
Параметр
typeуказывает тип ресурса,assetId— идентификатор загруженного ресурса,src— URL ресурса (обычно адрес сервера хостинга).Запомните
assetIdдля последующего подключения и освобождения ресурсов.try { await scene.assets.loadAsset({type: 'gltf', assetId: 'panda', src: 'url/EasyARPanda.glb'}); } catch (err) { console.error(`Failed to load assets: ${err.message}`); }Подключение узлов
Используйте
element.addChild(), чтобы поместить загруженную модель под ShadowRoot.const root = scene.getElementById("shadow-root"); let panda = scene.createElement(xrFrameSystem.XRGLTF, { "model": "panda", "anim-autoplay": "" } ); root.addChild(panda);Элемент ShadowRoot специально предназначен для динамического создания и удаления узлов. Подробнее см. Теневой узел.
Метод createXRNodeFromNodeAnnotation, предоставляемый объектом плагина, позволяет создавать дочерние узлы Block на основе данных EMA, гарантируя правильное расположение 3D-контента в пространстве.
const nodeAnnotation = annotation as easyar.ema.v0_5.Node; const xrNode: xrfs.XRNode = easyarPlugin.createXRNodeFromNodeAnnotation(nodeAnnotation, blockHolder); let panda = scene.createElement(xrFrameSystem.XRGLTF, { "model": "panda", "anim-autoplay": "" } ); xrNode.addChild(panda);
Как подключить контент под Block напрямую без аннотаций
Предупреждение
Используйте этот метод только если вы убедились, что значения LocalTransform в системе координат xr-frame обеспечивают ожидаемый результат рендеринга.
Во всех остальных случаях используйте функцию аннотирования в редакторе Unity.
Получите объект узла block в дереве сцены через getBlockById(id). Если узел отсутствует, значит Block ещё не был успешно локализован (узел создаётся автоматически при первой успешной локализации). Можно создать узел для этого Block с помощью holdBlock(blockInfo, blockTransformInput) или подключить контент после успешной локализации в колбэке.
Совет
В дереве сцены редактора Unity выберите узел Block и запишите его ID, отображаемый на панели Inspector.

Block ID также можно найти на странице облачной библиотеки локализации.

const blockID = "aaaa1234-bbbb-cccc-dddd-eeeeee123456"
if (!blockHolder.getBlockById(blockParent.id)) {
// Создать узел Block, если он отсутствует
blockHolder.holdBlock({
id: blockID
})
}
let blockElement = blockHolder.getBlockById(blockParent.id).el;
Подключите узел модели к указанному Block. Используйте position.setArray(), quaternion.set() и scale.setArray(), чтобы изменить LocalTransform узла модели.
export interface LocalTransform {
/** @description Позиция */
position: xrfs.Vector3;
/** @description Вращение */
rotation: xrfs.Quaternion;
/** @description Масштаб */
scale: xrfs.Vector3;
}
// Предположим, что известен LocalTransform относительно Block
const targetTransform: LocalTransform;
blockElement.addChild(modelNode);
let modelTransform = modelNode.getComponent(xrFrameSystem.Transform);
modelTransform.position.setArray([
targetTransform.position.x,
targetTransform.position.y,
targetTransform.position.z
]);
let annoRotation = new xrFrameSystem.Quaternion().setValue(
targetTransform.rotation.x,
targetTransform.rotation.y,
targetTransform.rotation.z,
targetTransform.rotation.w
);
modelTransform.quaternion.set(annoRotation);
modelTransform.scale.setArray([
targetTransform.scale.x,
targetTransform.scale.y,
targetTransform.scale.z
]);
Поддерживаемые типы ресурсов в xr-frame
- Texture (текстуры и изображения)
- CubeTexture (кубические текстуры)
- VideoTexture (видеотекстуры)
- EnvData (окружение)
- GLTF (модели)
- Keyframe (анимация по ключевым кадрам)
- Atlas (атласы)
Подробные методы загрузки для каждого типа ресурсов см. в официальной документации WeChat и официальных примерах xr-frame
Примечание
Поддерживаемые форматы GLTF и расширения см. в официальной спецификации GLTF для xr-frame