Table of Contents

Описание примера проекта для плагина Wechat Mini Program Mega

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

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

Как отображать модель в месте аннотации

  1. Точное размещение и загрузка маркеров в редакторе Unity, запись имени маркера и его идентификатора

    Расположение маркеров в 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. Замена маркера и загрузка модели

    Используйте "фабричный метод" xr-frame scene.createElement(xrFrameSystem.XRGLTF, options) в callback EMA для создания узла модели.

    • Параметры:

      • 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);
        /**
         * Для идентичности ориентации модели в 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. Запуск на устройстве

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

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

      Примечание

      Начало координат может находиться в произвольной точке пространства. Для размещения моделей используйте маркеры (см. Создание и загрузка маркеров в редакторе Unity).

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

      Примечание

      Начало координат может находиться в произвольной точке пространства. Для размещения моделей используйте маркеры (см. Создание и загрузка маркеров в редакторе Unity).

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

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

  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. Изменение коллбэка загрузки EMA

    В коллбэке загрузки 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}":
      Осторожно

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

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

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

      Результат: Создается куб, на поверхности которого воспроизводится видео.

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

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

    По подтверждению команды WeChat, это предупреждение не влияет на использование.

  3. Проверка на устройстве

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

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

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

  2. Загрузка GLTF в мини-программе xr-frame в качестве окклюзии.

    Загрузите ресурсы модели через 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. Загрузка модели и назначение материала окклюзии во время выполнения в обратном вызове загрузки EMA

    Создайте узел модели с помощью scene.createElement(xrFrameSystem.XRGLTF,options) в обратном вызове загрузки EMA.

    • Параметры:

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

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

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

    Присоедините модель к узлу метки через 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.

    Использование модели в позиции метки для окклюзии:

    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.

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