Table of Contents

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

Como exibir modelos na posição da anotação

  1. Posicionar e carregar anotações com precisão no editor Unity, registrando o nome e o ID da anotação

    Unity标注位置

  2. Adicionar recursos de modelo GLTF

    Adicione recursos de modelo em sampleAssets dentro de miniprogram/components/sample-easyar-mega/index.ts.

    const sampleAssets = {
        your_model_name: {
            assetId: "your_model_asset_id",
            type: "gltf",
            src: "url/model.glb",
            options: {}
        }
    }
    
  3. Carregar recursos de modelo adicionados

    Carregue o modelo na função loadAsset() dentro de miniprogram/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}`);
        }
    }
    
  4. 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"
        }
    };
    
  5. 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.scale ou "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);
    }
    
  6. 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).

      Modelos e oclusão

Como reproduzir vídeo transparente na posição da anotação

  1. 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}`);
        }
    }
    
  2. 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 material easyar-video-tsbs, e modificar o uniform para u_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 aviso wx.createVideoDecoder with type: 'wemedia' is deprecated no console, ignore.

    Confirmado com a equipe oficial do WeChat: este aviso não afeta o uso.

  3. Execução em dispositivo físico

Como posicionar modelos de oclusão alinhados espacialmente

  1. Posicione com precisão o modelo de oclusão e envie a marcação.

    Alinhamento preciso

  2. 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}`);
        }
    }
    
  3. 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.scale ou "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-occulusion sã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 });
            });
        }
    }
    
  4. Execução em dispositivo real

    Compare com resultados de simulação no editor Unity.

Tópicos relacionados