使用animation-mixer播放GLB文件,NFT激活时动画为何从中间启动?
解决NFT标记激活时GLB动画不从开头播放的问题
问题核心在于默认状态下,animation-mixer组件会在GLB模型加载完成后立刻自动播放动画,而非等到NFT标记被识别激活时才启动。所以当你第一次对准标记时,动画已经运行了一段时间,自然呈现从中间开始的状态。
解决步骤:
- 禁用
animation-mixer的自动播放功能 - 监听NFT标记的
markerFound事件,在标记被识别时手动重置并启动动画 - 可选:监听
markerLost事件,暂停动画,下次识别时重新从头播放
修改后的完整代码:
<div class="arjs-loader"> <div>Loading, please wait...</div> </div> <a-scene vr-mode-ui="enabled: false;" renderer="logarithmicDepthBuffer: true;" embedded arjs="trackingMethod: best; sourceType: webcam; debugUIEnabled: false;"> <a-assets> <a-asset-item id="dja" src="./arfile2.glb"></a-asset-item> </a-assets> <a-nft type='nft' url='./demo/marker/djarum' smooth='true' smoothCount='10' smoothTolerance='0.01' smoothThreshold='5'> <a-entity id="glbModel" gltf-model='#dja' scale="90 90 90" position="100 -200 0" rotation="-90 0 0" animation-mixer="autoplay: false" > </a-entity> </a-nft> <a-entity camera> </a-entity> </a-scene> <script> // 获取实体和动画混合器实例 const modelEl = document.querySelector('#glbModel'); let mixer; // 模型加载完成后初始化混合器 modelEl.addEventListener('model-loaded', () => { mixer = modelEl.components['animation-mixer'].mixer; }); // 标记被识别时启动动画 document.querySelector('a-nft').addEventListener('markerFound', () => { if (!mixer) return; // 获取第一个动画剪辑(多动画场景可指定剪辑名称) const action = mixer.clipAction(mixer._clipCache[0]); // 重置动画到开头并播放 action.time = 0; action.play(); }); // 可选:标记丢失时暂停动画 document.querySelector('a-nft').addEventListener('markerLost', () => { if (!mixer) return; mixer.stopAllAction(); }); </script>
关键说明:
- 给
animation-mixer添加autoplay: false,阻止模型加载后自动播放动画 - 通过
model-loaded事件确保模型完全加载后再获取动画混合器实例,避免操作未初始化的对象 - 在
markerFound事件触发时,强制将动画时间重置为0再启动,保证每次识别标记都从动画开头播放 - 可选的
markerLost事件处理,可让动画在标记离开视野时暂停,下次识别时继续(不需要从头播放可删除此部分)
内容的提问来源于stack exchange,提问作者narada project a
相关产品推荐
相关产品推荐

