Table of Contents

Descripción del proyecto de ejemplo del plugin Mega para mini programas de WeChat

Este artículo describe en detalle cómo usar las funciones mostradas en el proyecto de ejemplo, su implementación y las precauciones correspondientes.

Antes de comenzar

Cómo mostrar un modelo en la posición de una anotación

  1. Coloque y suba anotaciones con precisión en el editor Unity, y registre el nombre de la anotación y su ID

    Posición de anotación Unity

  2. Añadir recursos de modelo GLTF

    Añada el recurso de modelo a sampleAssets en 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. Cargar el recurso de modelo añadido

    Cargue el modelo en la función loadAsset() 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 las anotaciones que se reemplazarán

    Configure las anotaciones que se reemplazarán en miniprogram/components/sample-data/annotation-metadata.ts. Si se reemplazan varias, sepárelas con comas.

    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. Reemplazar anotaciones y cargar modelos

    En el callback después de cargar EMA, use el "método de fábrica" de xr-frame scene.createElement(xrFrameSystem.XRGLTF, options) para crear el nodo de modelo.

    • Parámetros:

      • xrFrameSystem.XRGLTF: especifica que el tipo de elemento que se creará es un modelo GLTF.
      • options: elementos de configuración de inicialización correspondientes a las propiedades del componente.
    • Propiedades clave en el código:

      • "model": obligatorio. Apunta al ID del recurso cargado (asset-id).
      • "anim-autoplay": opcional. Especifica el nombre de la animación que se reproduce automáticamente después de cargarse.
      • "scale": opcional. assetInfo.scale o "1 1 1".
      • name: obligatorio. Nombre de la anotación.
    Precaución

    Preste atención a distinguir las claves de propiedad de tipo string y no string, y rellénelas exactamente como en el ejemplo.

    Monte el modelo bajo el nodo de anotación con xrNode.addChild(child).

    Para garantizar que el modelo GLTF se vea igual con los cargadores de distintas plataformas, rote el modelo cargado 180 grados alrededor del eje Y en el mismo lugar.

    if (assetInfo && assetInfo.assetId && assetInfo.assetId.trim().length > 0) {
        model = scene.createElement(
            xrFrameSystem.XRGLTF,
            {
                /** assetId del paso anterior */
                "model": assetInfo.assetId,
                /** Aquí se puede especificar la animación del modelo que se reproducirá */
                "anim-autoplay": assetInfo.animation ? assetInfo.animation : "",
                "scale": assetInfo.scale ? assetInfo.scale : "1 1 1",
                name: emaName
            }
        );
        xrNode.addChild(model);
        /**
         * Debido a diferencias en el comportamiento de los cargadores GLTF, para que la orientación del modelo en xr-frame coincida exactamente con el resultado renderizado en Unity
         * El modelo cargado debe rotarse 180 grados alrededor del eje Y en el lugar
         */
        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. Ejecución en dispositivo real

    • El resultado de la ejecución en dispositivo real se muestra a continuación y puede compararse con la posición en el editor Unity del paso 1:

    • Active el botón de vídeo transparente de la izquierda. En el origen del sistema de coordenadas mundial, la posición (0, 0, 0), aparecerá un cubo con material de vídeo transparente.

      Nota

      La posición del origen puede ser una posición aleatoria en el espacio. Puede usar anotaciones para colocar el modelo de oclusión en la posición deseada. Consulte crear y subir anotaciones con el editor Unity.

    • Active el botón de oclusión de la izquierda. En el origen del sistema de coordenadas mundial, la posición (0, 0, 0), aparecen un modelo de panda y cubos apilados verticalmente. El cubo central tiene material de oclusión, y al otro lado hay un modelo de panda estático con material de oclusión.

      Nota

      La posición del origen puede ser una posición aleatoria en el espacio. Puede usar anotaciones para colocar el modelo de oclusión en la posición deseada. Consulte crear y subir anotaciones con el editor Unity.

      Modelo y oclusión

Cómo reproducir un video transparente en la posición de una anotación

  1. Cargar un recurso de video cuyo tipo sea video-texture.

    async loadAsset() {
        const videoTexture = {
            assetId: "fireball",
            type: "video-texture",
            // 视频资源 URL
            src: "url/video-resource.mp4",
            options: {
                autoPlay: true,
                loop: true,
            }
        };
        try {
            // 加载 video-texture 类型资源
            await scene.assets.loadAsset(videoTexture);
        } catch (err) {
            console.error(`Failed to load video texture: ${err.message}`);
        }
    }
    
  2. Modificar el callback de carga de EMA

    En el callback de carga de EMA, use scene.createElement(xrFrameSystem.XRMesh,options) para crear una geometría simple, asígnele el material easyar-video-tsbs y cambie uniform a u_baseColorMap:video-{$assetId}.

    • Parámetros:

      • xrFrameSystem.XRMesh: especifica que el tipo de elemento creado es una geometría básica.
      • options: elementos de configuración de inicialización, correspondientes a las propiedades del componente.
    • Propiedades clave en el código:

      • "geometry": "cube": usa los datos de geometría de cubo integrados en xr-frame.
      • "material": "easyar-video-tsbs": especifica un material predefinido. Por el nombre, se presume que es un material especial compatible con texturas de video.
      • "uniforms": "u_baseColorMap:video-{$assetId}":
      Precaución

      Preste atención a distinguir entre claves de propiedad de tipo string y no string, y rellénelas exactamente como se muestra en el ejemplo.

      Esto es una vinculación dinámica de un parámetro de material.

      Mapea el recurso de video (textura) llamado video-{$assetId} al mapa de color base del material.

      Efecto: se genera un cubo cuya superficie reproduce video.

    model = scene.createElement(xrFrameSystem.XRMesh, {
        geometry: "cube",
        material: "easyar-video-tsbs",
        uniforms: "u_baseColorMap:video-fireball",
    });
    xrNode.addChild(model);
    
    Nota

    Al usar video-texture, si la console muestra la advertencia wx.createVideoDecoder with type: 'wemedia' is deprecated, ignórela.

    Hemos confirmado con el equipo oficial de WeChat que esta advertencia no afecta al uso.

  3. Ejecutar en un dispositivo real

Cómo colocar un modelo de oclusión alineado con el espacio

  1. Coloque con precisión el modelo usado para occlusion y suba la anotación.

    Alineación precisa

  2. Cargue el GLTF usado como occlusion en el xr-frame Mini Program.

    Cargue el recurso del modelo mediante scene.assets.loadAsset() (requiere descarga 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. En runtime, cargue el modelo en el callback de carga de EMA y asigne el material de occlusion

    Use scene.createElement(xrFrameSystem.XRGLTF,options) en el callback de carga de EMA para crear el nodo de modelo.

    • Parámetros:

      • xrFrameSystem.XRGLTF: especifica que el tipo de elemento creado es un modelo GLTF.
      • options: elementos de configuración de inicialización, correspondientes a las propiedades del componente.
    • Propiedades clave en el código:

      • "model": obligatorio, apunta al ID del recurso cargado (asset-id).
      • "scale": opcional, assetInfo.scale o "1 1 1".
      • name: obligatorio, nombre de la anotación.
    Precaución

    Preste atención a distinguir las property Keys de cadena y no cadena, y rellene exactamente como en el ejemplo.

    Monte el modelo bajo el nodo de anotación con xrNode.addChild(child).

    Para garantizar que el modelo GLTF se vea igual con loaders en distintas plataformas, rote el modelo cargado 180 grados alrededor del eje Y en su lugar.

    Finalmente, use model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {m.setData({ neverCull: true, material: occlusionMaterial });} para modificar el material del modelo GLTF.

    Nota

    La carga, registro, desregistro y descarga del material easyar-occulusion son controlados por AR Session.

    Use el modelo en la posición de anotación como occlusion:

    if (...) {
        model = scene.createElement(
            xrFrameSystem.XRGLTF,
            {
                "model": assetInfo.assetId,
                "scale": assetInfo.scale ? assetInfo.scale : "1 1 1",
                name: emaName
            }
        );
        /**
        * Debido a diferencias en el comportamiento de los cargadores GLTF, para que la orientación del modelo en xr-frame coincida exactamente con el resultado renderizado en Unity,
        * a veces hay que rotar el modelo cargado 180 grados alrededor del eje Y en el lugar
        */
        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);
        // Nota: el material debe modificarse después de modificar Transform
        if (assetInfo.assetId == 'occlusion1') {
            // Obtener el material de oclusión proporcionado por el plugin Mega
            let occlusionMaterial = scene.assets.getAsset("material", "easyar-occlusion");
            // Modificar el material de oclusión
            model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {
                m.setData({ neverCull: true, material: occlusionMaterial });
            });
        }
    }
    
  4. Ejecutar en un dispositivo real

    Compare con el resultado de ejecución simulada en Unity editor.

Temas relacionados