如何在A-Frame 1.3.0中适配原0.8.2可用的wave-component?
A-Frame 1.3.0 适配 wave-component 解决方案
问题核心原因
你的组件失效是因为A-Frame 1.3.0依赖的Three.js版本(r132)相比0.8.2的旧版本,在几何体顶点操作、动画循环机制上有重大API变更,旧代码的顶点遍历、更新逻辑已不再兼容。
适配后的完整代码
<script> AFRAME.registerComponent('wave-component', { schema: { texturepath: {type: 'asset'} }, init: function () { const el = this.el; const loader = new THREE.TextureLoader(); // 新版Three.js中PlaneGeometry默认是BufferGeometry,替代旧版Geometry const geometry = new THREE.PlaneGeometry(10, 3, 100, 60); // 直接使用A-Frame asset对象,无需手动提取src const material = new THREE.MeshBasicMaterial({ map: loader.load(this.data.texturepath), transparent: true }); this.wave = new THREE.Mesh(geometry, material); this.wave.rotation.set(-0.3, 0.0, -0.0); el.setObject3D('WaveMesh', this.wave); // 缓存顶点位置数组与顶点数量,减少重复查询提升性能 this.positions = this.wave.geometry.attributes.position.array; this.vertexCount = this.positions.length / 3; }, // 使用A-Frame内置tick方法替代自定义requestAnimationFrame,与引擎渲染循环同步 tick: function (time, timeDelta) { const t = time / 1000; // 转换为秒级时间单位 for (let i = 0; i < this.vertexCount; i++) { const x = this.positions[i * 3]; const y = this.positions[i * 3 + 1]; const waveX1 = 0.15 * Math.sin(x * 2 + t * 3); const waveX2 = 0.05 * Math.sin(x * 5 + t * 2); const waveY1 = 0.1 * Math.sin(y * 10 + t * 0.5); const multi = (x + 0.1) / 5; // 更新顶点z轴坐标 this.positions[i * 3 + 2] = (waveX1 + waveX2 + waveY1) * multi; } // 通知Three.js顶点数据已更新 this.wave.geometry.attributes.position.needsUpdate = true; } }); </script>
关键修改点说明
- 顶点数据访问:旧版本
geometry.vertices已被移除,新版BufferGeometry通过attributes.position.array访问原始顶点数据,需按x/y/z顺序遍历(每3个元素对应一个顶点)。 - 动画循环优化:替换自定义
requestAnimationFrame为A-Frame组件的tick方法,该方法与引擎渲染循环同步,避免冲突,且直接提供时间参数无需手动创建Clock。 - 更新标记变更:旧
verticesNeedUpdate属性已废弃,改用geometry.attributes.position.needsUpdate = true通知Three.js重新计算顶点数据。 - Asset处理简化:A-Frame的
asset类型会自动解析资源路径,直接使用this.data.texturepath即可,无需额外提取.src。
内容的提问来源于stack exchange,提问作者Rodrigo Olmedo
相关产品推荐
相关产品推荐

