Exemplo de projeto de plug-in Mega para mini-programa WeChat
Este artigo explica detalhadamente os métodos de uso, implementação e considerações para cada funcionalidade demonstrada no projeto de exemplo.
Antes de começar
- Ser capaz de criar e fazer upload de anotações usando o editor Unity e registrar os nomes das anotações e seus IDs.
- Ser capaz de criar conteúdo 3D alinhado com o mundo real usando o editor Unity.
- Ser capaz de executar completamente o projeto de exemplo.
Como exibir modelos na posição da anotação
Posicionar e carregar anotações com precisão no editor Unity, registrando o nome e o ID da anotação

Adicionar recursos de modelo GLTF
Adicione recursos de modelo em
sampleAssetsdentro deminiprogram/components/sample-easyar-mega/index.ts.const sampleAssets = { your_model_name: { assetId: "your_model_asset_id", type: "gltf", src: "url/model.glb", options: {} } }Carregar recursos de modelo adicionados
Carregue o modelo na função
loadAsset()dentro deminiprogram/components/sample-easyar-mega/index.ts.async loadAsset() { try { await scene.assets.loadAsset(sampleAssets.your_model_name); } catch (err) { console.error(`Failed to load assets: ${err.message}`); } }Configurar anotações para substituição
Configure as anotações a serem substituídas em
miniprogram/components/sample-data/annotation-metadata.ts. Separe múltiplas IDs com vírgulas.export const AnnotationMetaData: Record<string, any> = { "aaaaaaaa-bbbb-cccc-dddd-123456789012": { assetId: "panda", scale: "0.5 0.5 0.5" }, "aaaaaaaa-bbbb-cccc-dddd-123456789013": { assetId: "your_model_asset_id", scale: "1 1 1" } };Substituir anotação para carregar modelo
Use o método "factory"
scene.createElement(xrFrameSystem.XRGLTF, options)no callback de carregamento do EMA para criar o nó do modelo.Parâmetros:
xrFrameSystem.XRGLTF: Especifica o tipo de elemento como modelo GLTF.options: Configurações de inicialização, correspondendo aos atributos do componente.
Atributos chave:
"model": Obrigatório, ID do recurso carregado (asset-id)."anim-autoplay": Opcional, nome da animação para reprodução automática."scale": Opcional,assetInfo.scaleou "1 1 1".name: Obrigatório, nome da anotação.
Cuidado
Distinga entre chaves de propriedade string e não-string. Preencha exatamente como no exemplo.
Monte o modelo sob o nó de anotação usando
xrNode.addChild(child).Para garantir consistência visual entre plataformas, aplique uma rotação de 180° no eixo Y após o carregamento.
if (assetInfo && assetInfo.assetId && assetInfo.assetId.trim().length > 0) { model = scene.createElement( xrFrameSystem.XRGLTF, { "model": assetInfo.assetId, "anim-autoplay": assetInfo.animation ? assetInfo.animation : "", "scale": assetInfo.scale ? assetInfo.scale : "1 1 1", name: emaName } ); xrNode.addChild(model); /** * Rotacionar 180° no eixo Y para compatibilidade com o renderizador do Unity */ let modelTransform = model.getComponent(xrFrameSystem.Transform); let currentRotation = modelTransform.quaternion.clone(); let targetRotation = currentRotation.multiply(new xrFrameSystem.Quaternion().setValue(0, 1, 0, 0)); modelTransform.quaternion.set(targetRotation); }Execução no dispositivo real
Resultado comparável ao posicionamento no Unity (passo 1):
Ative o botão de vídeo transparente para exibir um cubo na origem do sistema de coordenadas (0,0,0):
Nota
A origem pode estar em qualquer posição espacial. Use anotações para posicionar modelos de oclusão conforme necessário (ver criação de anotações).
Ative o botão de oclusão para exibir na origem:
- Modelo de panda
- Cubos empilhados (um com material de oclusão)
- Panda estático com material de oclusão
Nota
Posicione modelos de oclusão usando anotações (ver criação de anotações).

Como reproduzir vídeo transparente na posição da anotação
Carregar ativos de vídeo do tipo
video-texture.async loadAsset() { const videoTexture = { assetId: "fireball", type: "video-texture", // URL do recurso de vídeo src: "url/video-resource.mp4", options: { autoPlay: true, loop: true, } }; try { // Carregar recurso do tipo video-texture await scene.assets.loadAsset(videoTexture); } catch (err) { console.error(`Failed to load video texture: ${err.message}`); } }Modificar o callback de carregamento do EMA
No callback de carregamento do EMA, usar
scene.createElement(xrFrameSystem.XRMesh,options)para criar uma geometria simples com materialeasyar-video-tsbs, e modificar ouniformparau_baseColorMap:video-{$assetId}.Parâmetros:
xrFrameSystem.XRMesh: Especifica o tipo de elemento como geometria básica.options: Configurações de inicialização, correspondendo aos atributos do componente.
Atributos-chave no código:
"geometry": "cube": Usa dados geométricos internos de cubo do xr-frame."material": "easyar-video-tsbs": Especifica um material predefinido (por nome, um material especial que suporta textura de vídeo)."uniforms": "u_baseColorMap:video-{$assetId}":
Cuidado
Observe a distinção entre chaves de propriedade string e não-string, preencha exatamente como no exemplo.
Isto é o binding dinâmico de parâmetros de material.
Mapeia o recurso de vídeo (textura) chamado
video-{$assetId}para o mapa de cor base do material.Efeito: Cria um cubo com superfície reproduzindo vídeo.
model = scene.createElement(xrFrameSystem.XRMesh, { geometry: "cube", material: "easyar-video-tsbs", uniforms: "u_baseColorMap:video-fireball", }); xrNode.addChild(model);Nota
Ao usar
video-texture, se aparecer o avisowx.createVideoDecoder with type: 'wemedia' is deprecatedno console, ignore.Confirmado com a equipe oficial do WeChat: este aviso não afeta o uso.
Execução em dispositivo físico
Como posicionar modelos de oclusão alinhados espacialmente
Posicione com precisão o modelo de oclusão e envie a marcação.

Carregue o GLTF como oclusão no mini-programa xr-frame.
Utilize
scene.assets.loadAsset()para carregar recursos de modelo (requer descarregamento manual).const sampleAssets = { occlusion1: { assetId: "occlusion1", type: "gltf", src: "url/occlusion1.glb", options: {} } } async loadAsset() { if (!scene) {console.error("Empty scene"); return;} try { await scene.assets.loadAsset(sampleAssets.occlusion1); } catch (err) { console.error(`Failed to load assets: ${err.message}`); } }Em tempo de execução, carregue o modelo e aplique material de oclusão no callback de carregamento da EMA
No callback de carregamento da EMA, use
scene.createElement(xrFrameSystem.XRGLTF,options)para criar um nó de modelo.Parâmetros:
xrFrameSystem.XRGLTF: Especifica o tipo de elemento como modelo GLTF.options: Configurações iniciais, correspondendo aos atributos do componente.
Atributos-chave no código:
"model": Obrigatório. ID do recurso (asset-id) pré-carregado."scale": Opcional.assetInfo.scaleou "1 1 1".name: Obrigatório. Nome da marcação.
Cuidado
Distinga entre chaves de propriedade como string e não-string. Preencha exatamente como no exemplo.
Monte o modelo sob o nó de marcação via
xrNode.addChild(child).Para garantir consistência visual entre plataformas, rotacione o modelo carregado 180° no eixo Y após o carregamento.
Finalmente, use
model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {m.setData({ neverCull: true, material: occlusionMaterial });}para alterar o material do modelo GLTF.Nota
O carregamento, registro, desregistro e descarregamento do material
easyar-occulusionsão controlados pela AR Session.Uso do modelo como oclusão na posição marcada:
if (...) { model = scene.createElement( xrFrameSystem.XRGLTF, { "model": assetInfo.assetId, "scale": assetInfo.scale ? assetInfo.scale : "1 1 1", name: emaName } ); /** * Devido a variações no carregador GLTF, rotacione 180° no eixo Y para alinhar * a renderização do xr-frame com os resultados do Unity */ let modelTransform = model.getComponent(xrFrameSystem.Transform); let currentRotation = modelTransform.quaternion.clone(); let targetRotation = currentRotation.multiply(new xrFrameSystem.Quaternion().setValue(0, 1, 0, 0)); modelTransform.quaternion.set(targetRotation); //Altere o material APÓS modificar a Transform if (assetInfo.assetId == 'occlusion1') { //Obtenha o material de oclusão do plug-in mega let occlusionMaterial = scene.assets.getAsset("material", "easyar-occlusion"); //Aplique o material model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => { m.setData({ neverCull: true, material: occlusionMaterial }); }); } }Execução em dispositivo real
Compare com resultados de simulação no editor Unity.