Как загружать 3D-контент в AR-сцене во время выполнения в xr-frame
Эта статья подробно описывает механизм разделения resource loading и node mounting в xr-frame. С помощью динамического script 3D-контент можно гибко монтировать под node Block для реализации AR.
Официальные материалы
- Руководство по разработке xr-frame: официальная документация XR engine WeChat.
- Официальные примеры xr-frame: содержит различные базовые и продвинутые примеры использования.
В официальных материалах уже достаточно описано, как загружать 3D-контент во время выполнения. В этой статье кратко объясняются только некоторые часто используемые в AR-сценах материалы и способы загрузки.
Resource loading vs node mounting
В xr-frame отображение 3D-модели делится на два этапа:
Resource loading: загрузка файла модели (например,
.glb) из сети или локального хранилища и разбор его в память. На этом этапе модель готова, но в scene ещё не видна.Node mounting: создание node в scene tree и связывание загруженного resource с этим node. Только после этого модель появляется на rendering canvas.
Как динамически загружать 3D-контент с помощью кода
Resource loading
Вручную загрузите resource, вызвав loadAsset через систему управления resources xr-frame scene.
typeв параметрах означает тип resource,assetId— id resource после загрузки, аsrc— url resource, обычно адрес сервера размещения resources.Запишите
assetIdдля последующего mounting и освобождения resource.try { await scene.assets.loadAsset({type: 'gltf', assetId: 'panda', src: 'url/EasyARPanda.glb'}); } catch (err) { console.error(`Failed to load assets: ${err.message}`); }Node mounting
Используйте
element.addChild(), чтобы поместить загруженную модель под ShadowRoot.const root = scene.getElementById("shadow-root"); let panda = scene.createElement(xrFrameSystem.XRGLTF, { "model": "panda", "anim-autoplay": "" } ); root.addChild(panda);Элемент ShadowRoot — это специальный root node xr-frame для предотвращения динамического создания и удаления nodes. Подробнее см. Shadow node.
Метод createXRNodeFromNodeAnnotation, предоставляемый plugin object, может создавать child nodes 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 без annotation
Предупреждение
Предварительное условие использования этого метода: вы уже проверили, что значение LocalTransform в координатной системе xr-frame даёт ожидаемый rendering effect.
Во всех остальных случаях используйте функцию annotation Unity Editor.
Получите object node block в scene tree через getBlockById(id). Если соответствующий block node не существует, значит localization для этого Block ещё ни разу не была успешной (node будет создан автоматически при первой успешной localization этого Block). Можно использовать holdBlock(blockInfo, blockTransformInput) для создания node этого Block или в localization callback дождаться успешной localization Block перед mounting контента.
Совет
Выберите node Block в scene tree Unity Editor и запишите ID, отображаемый на панели Inspector

Block ID также можно найти на странице cloud localization library

const blockID = "aaaa1234-bbbb-cccc-dddd-eeeeee123456"
if (!blockHolder.getBlockById(blockParent.id)) {
// узел Block отсутствует; создайте его
blockHolder.holdBlock({
id: blockID
})
}
let blockElement = blockHolder.getBlockById(blockParent.id).el;
Смонтируйте model node под указанным Block, затем используйте position.setArray(), quaternion.set() и scale.setArray(), чтобы изменить LocalTransform model node.
export interface LocalTransform {
/** @description позиция */
position: xrfs.Vector3;
/** @description поворот */
rotation: xrfs.Quaternion;
/** @description Scale */
scale: xrfs.Vector3;
}
// предположим, что под Block есть известный LocalTransform
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
]);
Типы resources, поддерживаемые xr-frame
- Texture, текстуры и изображения
- CubeTexture, кубические текстуры
- VideoTexture, видеотекстуры
- EnvData, environment
- GLTF models
- Keyframe, frame animation
- Atlas
Подробные способы загрузки каждого resource см. в официальной документации WeChat и официальных примерах xr-frame
Примечание
О поддерживаемых форматах и extensions GLTF см. официальную инструкцию xr-frame по использованию GLTF