Table of Contents

Описание примерного проекта плагина Mega для мини-программы WeChat

В этой статье подробно описаны способы использования функций, показанных в примерном проекте, их реализация и важные замечания.

Перед началом

Как отобразить модель в позиции annotation

  1. Точно разместите и загрузите аннотации в редакторе Unity, затем запишите имя аннотации и ее ID

    Положение аннотации Unity

  2. Добавление ресурсов модели GLTF

    Добавьте ресурс модели в sampleAssets в 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. Загрузка добавленного ресурса модели

    Загрузите модель в функции loadAsset() в 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. Настройка аннотаций для замены

    Настройте аннотации для замены в miniprogram/components/sample-data/annotation-metadata.ts. Если нужно заменить несколько аннотаций, разделите их запятыми.

    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. Замена аннотаций и загрузка моделей

    В callback после загрузки EMA используйте «фабричный метод» xr-frame scene.createElement(xrFrameSystem.XRGLTF, options), чтобы создать узел модели.

    • Параметры:

      • xrFrameSystem.XRGLTF: указывает, что создаваемый тип элемента является моделью GLTF.
      • options: параметры конфигурации инициализации, соответствующие свойствам компонента.
    • Ключевые свойства в коде:

      • "model": обязательно. Указывает на ID загруженного ресурса (asset-id).
      • "anim-autoplay": необязательно. Задает имя анимации, которая автоматически воспроизводится после загрузки.
      • "scale": необязательно. assetInfo.scale или "1 1 1".
      • name: обязательно. Имя аннотации.
    Осторожно

    Обратите внимание на различие строковых и нестроковых ключей свойств и заполняйте их точно как в примере.

    Прикрепите модель к узлу аннотации с помощью xrNode.addChild(child).

    Чтобы модель GLTF выглядела одинаково в загрузчиках на разных платформах, поверните загруженную модель на 180 градусов вокруг оси Y на месте.

    if (assetInfo && assetInfo.assetId && assetInfo.assetId.trim().length > 0) {
        model = scene.createElement(
            xrFrameSystem.XRGLTF,
            {
                /** assetId из предыдущего шага */
                "model": assetInfo.assetId,
                /** Здесь можно указать анимацию модели для воспроизведения */
                "anim-autoplay": assetInfo.animation ? assetInfo.animation : "",
                "scale": assetInfo.scale ? assetInfo.scale : "1 1 1",
                name: emaName
            }
        );
        xrNode.addChild(model);
        /**
         * Из-за различий в поведении загрузчиков GLTF, чтобы ориентация модели в xr-frame полностью совпадала с результатом рендеринга Unity
         * Загруженную модель необходимо повернуть на месте на 180 градусов вокруг оси Y
         */
        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. Запуск на устройстве

    • Результат запуска на устройстве показан ниже; его можно сравнить с положением в редакторе Unity из шага 1:

    • Включите кнопку прозрачного видео слева. В начале мировой системы координат, в позиции (0, 0, 0), появится куб с материалом прозрачного видео.

      Примечание

      Положение начала координат может быть случайным местом в пространстве. Можно использовать аннотации, чтобы разместить модель окклюзии в нужном месте. Подробнее см. создание и загрузка аннотаций с помощью редактора Unity.

    • Включите кнопку окклюзии слева. В начале мировой системы координат, в позиции (0, 0, 0), появятся модель панды и вертикально расположенные кубы. Средний куб имеет материал окклюзии, а с другой стороны находится статическая модель панды с материалом окклюзии.

      Примечание

      Положение начала координат может быть случайным местом в пространстве. Можно использовать аннотации, чтобы разместить модель окклюзии в нужном месте. Подробнее см. создание и загрузка аннотаций с помощью редактора Unity.

      Модель и окклюзия

Как воспроизвести прозрачное видео в позиции annotation

  1. Загрузите видео-ресурс с типом 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. Измените callback загрузки EMA

    В callback загрузки EMA используйте scene.createElement(xrFrameSystem.XRMesh,options), чтобы создать простую геометрию, назначьте ей материал easyar-video-tsbs и измените uniform на u_baseColorMap:video-{$assetId}.

    • Параметры:

      • xrFrameSystem.XRMesh: указывает, что создаваемый элемент является базовой геометрией.
      • options: параметры инициализации, соответствующие свойствам компонента.
    • Ключевые свойства в коде:

      • "geometry": "cube": использует встроенные в xr-frame геометрические данные куба.
      • "material": "easyar-video-tsbs": задает предопределенный материал. Судя по названию, это специальный материал с поддержкой видеотекстур.
      • "uniforms": "u_baseColorMap:video-{$assetId}":
      Осторожно

      Обратите внимание на различие между строковыми и нестроковыми property Key и заполняйте их строго так, как показано в примере.

      Это динамическая привязка параметра материала.

      Она сопоставляет видео-ресурс (текстуру) с именем video-{$assetId} с картой базового цвета материала.

      Эффект: создается куб, на поверхности которого воспроизводится видео.

    model = scene.createElement(xrFrameSystem.XRMesh, {
        geometry: "cube",
        material: "easyar-video-tsbs",
        uniforms: "u_baseColorMap:video-fireball",
    });
    xrNode.addChild(model);
    
    Примечание

    При использовании video-texture, если в console появляется предупреждение wx.createVideoDecoder with type: 'wemedia' is deprecated, игнорируйте его.

    Мы подтвердили с официальной командой WeChat, что это предупреждение не влияет на использование.

  3. Запуск на реальном устройстве

Как разместить модель occlusion, выровненную с пространством

  1. Точно разместите модель, используемую для occlusion, и загрузите аннотацию.

    Точное выравнивание

  2. Загрузите GLTF, используемый как occlusion, в xr-frame Mini Program.

    Загрузите ресурс модели через scene.assets.loadAsset() (требуется ручная выгрузка).

    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. Во время выполнения загрузите модель в callback загрузки EMA и назначьте материал occlusion

    Используйте scene.createElement(xrFrameSystem.XRGLTF,options) в callback загрузки EMA для создания узла модели.

    • Параметры:

      • xrFrameSystem.XRGLTF: указывает, что создаваемый тип элемента является GLTF-моделью.
      • options: элементы конфигурации инициализации, соответствующие свойствам компонента.
    • Ключевые свойства в коде:

      • "model": обязательно, указывает на ID загруженного ресурса (asset-id).
      • "scale": необязательно, assetInfo.scale или "1 1 1".
      • name: обязательно, имя аннотации.
    Осторожно

    Обратите внимание на различие строковых и нестроковых property Key, заполняйте строго как в примере.

    Смонтируйте модель под узлом аннотации с помощью xrNode.addChild(child).

    Чтобы GLTF-модель выглядела одинаково в загрузчиках на разных платформах, поверните загруженную модель на 180 градусов вокруг оси Y на месте.

    В конце используйте model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {m.setData({ neverCull: true, material: occlusionMaterial });} для изменения материала GLTF-модели.

    Примечание

    Загрузка, регистрация, отмена регистрации и выгрузка материала easyar-occulusion контролируются AR Session.

    Используйте модель в позиции аннотации как occlusion:

    if (...) {
        model = scene.createElement(
            xrFrameSystem.XRGLTF,
            {
                "model": assetInfo.assetId,
                "scale": assetInfo.scale ? assetInfo.scale : "1 1 1",
                name: emaName
            }
        );
        /**
        * Из-за различий в поведении загрузчиков GLTF, чтобы ориентация модели в xr-frame полностью совпадала с результатом рендеринга Unity,
        * иногда после загрузки модель нужно повернуть на месте на 180 градусов вокруг оси Y
        */
        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);
        // Примечание: материал необходимо изменить после изменения Transform
        if (assetInfo.assetId == 'occlusion1') {
            // Получить материал окклюзии, предоставляемый плагином Mega
            let occlusionMaterial = scene.assets.getAsset("material", "easyar-occlusion");
            // Изменить материал окклюзии
            model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {
                m.setData({ neverCull: true, material: occlusionMaterial });
            });
        }
    }
    
  4. Запуск на реальном устройстве

    Сравните с результатом симуляции выполнения в Unity editor.

Связанные темы