You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法在碰撞事件中移除dynamic-body组件:TypeError错误排查

AFRAME碰撞处理组件移除属性触发TypeError问题排查

问题概述

在AFRAME开发中,注册collision-handler组件实现逻辑:当通过superhands抓取的#knife实体与#fruit实体碰撞时,移除#fruit的dynamic-body和body-merger组件。但在collide事件监听内执行移除操作时,会触发TypeError: _bi2 is undefined错误;将移除代码放在监听外部则无异常。

相关代码

组件代码

AFRAME.registerComponent('collision-handler', {
  init: function () {
    var el = this.el;
    var sceneEl = document.getElementsByTagName('a-scene');
    var fruit = document.getElementById("#fruit");
    el.addEventListener('collide', function collision (event) {
      var collidedEntity = event.detail.body.el;
        if (collidedEntity.id === '#fruit') {
          fruit.removeAttribute('body-merger: dynamic-body');
          fruit.removeAttribute('dynamic-body');
          // fruit.removeAttribute('scale');
          el.removeEventListener('collide', collision);
          console.log('Collided with entity with ID "#fruit"');
        }
    });
    // fruit.removeAttribute('dynamic-body');
    // fruit.removeAttribute('body-merger: dynamic-body');
  }
});

实体结构

<a-entity id="#fruit" position="1.5 2 -2" dynamic-body mixin="interactable" body-merger="dynamic-body" scale="0.5 0.5 0.5">
  <a-box mixin="cube" dynamic-body position="0 0 0" color="blue"></a-box>
  <a-box mixin="cube" dynamic-body position="-0.5 0 0" color="red"></a-box>
  <a-box mixin="cube" dynamic-body position="0.5 0 0" color="green"></a-box>
</a-entity>
<a-box id="#knife" position="0.5 2 -2" static-body mixin="interactable" geometry="width: 0.25; height: 0.25; depth: 1" color="purple" collision-handler></a-box>

依赖包

<script src="https://aframe.io/releases/1.5.0/aframe.js"></script>
<script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-physics-system@v4.1.0/dist/aframe-physics-system.js"></script>
<script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-extras@7.2.0/dist/aframe-extras.min.js"></script>
<script src="https://unpkg.com/aframe-physics-extras/dist/aframe-physics-extras.min.js"></script>

问题原因及解决方法

1. ID定义与选择错误

实体的id属性不需要带#符号,当前代码中id="#fruit"、id="#knife"的写法不符合规范,会导致document.getElementById("#fruit")无法正确获取元素,后续操作因元素为null触发异常。

修正点:

  • 实体ID改为id="fruit"、id="knife"
  • 获取元素改为document.getElementById("fruit")
  • 碰撞判断条件改为collidedEntity.id === "fruit"

2. 移除属性语法错误

removeAttribute方法只需传入属性名,不需要带属性值部分,当前fruit.removeAttribute('body-merger: dynamic-body')写法错误,应改为fruit.removeAttribute('body-merger')。

3. 物理引擎同步冲突

在collide事件回调中直接修改物理组件,会打断物理引擎当前帧的更新流程,导致内部引用丢失(即报错中的_bi2变量未定义)。需将移除操作延迟到下一帧,让物理引擎完成当前处理后再执行修改。

修正后的代码

组件代码

AFRAME.registerComponent('collision-handler', {
  init: function () {
    var el = this.el;
    var fruit = document.getElementById("fruit");
    el.addEventListener('collide', function collision (event) {
      var collidedEntity = event.detail.body.el;
      if (collidedEntity.id === "fruit") {
        // 延迟执行避免打断物理引擎流程
        requestAnimationFrame(() => {
          fruit.removeAttribute('body-merger');
          fruit.removeAttribute('dynamic-body');
          el.removeEventListener('collide', collision);
          console.log('Collided with entity with ID "fruit"');
        });
      }
    });
  }
});

实体代码

<a-entity id="fruit" position="1.5 2 -2" dynamic-body mixin="interactable" body-merger="dynamic-body" scale="0.5 0.5 0.5">
  <a-box mixin="cube" dynamic-body position="0 0 0" color="blue"></a-box>
  <a-box mixin="cube" dynamic-body position="-0.5 0 0" color="red"></a-box>
  <a-box mixin="cube" dynamic-body position="0.5 0 0" color="green"></a-box>
</a-entity>
<a-box id="knife" position="0.5 2 -2" static-body mixin="interactable" geometry="width: 0.25; height: 0.25; depth: 1" color="purple" collision-handler></a-box>

内容的提问来源于stack exchange,提问作者Eduard Koczi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 16:38:19