Сфера физики Афраме при столкновении разбивается на более мелкие сферы

В моей игре я делаю сферу (созданную с использованием a-сферы), динамическое тело, сталкиваюсь с другим динамическим телом (a-box).

При столкновении сфера разбивается на несколько более мелких сфер. Мне нужно остановить этот распад

Вот кодовая ручка - сфера разрывается при столкновении с динамическим телом

Вот сопроводительный код -

HTML

<a-scene physics="debug: true; gravity: -5.0">
  <a-entity camera="userHeight: 1.6"
                look-controls
                kinematic-body>
        <a-entity cursor
                  position="0 0 -1"
                  geometry="primitive: circle; radius: 0.01; segments: 4;"
                  material="color: #FF4444; shader: flat"></a-entity>
    <a-entity position="0 0 1" id="attachment"></a-entity>
  </a-entity>

  <a-entity geometry="primitive: box; height:2" material="color: black; shader: flat" position="0 2 -5" dynamic-body></a-entity>

  <a-plane static-body color="#ccc" height="100" width="100" position="0 -0.1 0" rotation="-90 0 0"></a-plane>
</a-scene>

и JS

const scene = document.querySelector('a-scene');
const camera = document.querySelector('[camera]');
const attachment = document.querySelector('#attachment');

function spawnBullet() {
    let entity = document.createElement('a-sphere');
    let impulseAmount = 8;

    entity.setAttribute('radius', 1);
    // Set initial position of projectile to that of the camera.
    entity.setAttribute('position', camera.getAttribute('position'));
    entity.setAttribute('color', '#00FFCC');
    entity.setAttribute('shader', 'flat');
    entity.setAttribute('mass', 10);

    // Append projectile to the scene, not to the camera, to
    // avoid all sorts of complications. Most notably, CANNON.js
    // has no scene graph or nesting.
    scene.appendChild(entity);

    entity.setAttribute('dynamic-body', true);  

    entity.addEventListener('body-loaded', function(){
      // Can't apply forces during the same tick that attaches the body, because
      // it hasn't been fully synced to the physics sim. (bug)
      setTimeout(function () {
        let pStart = new CANNON.Vec3();
        // Use an origin point behind the head, not at the head, so
        // there's a useful vector between the origin and the projectile.
        pStart.copy(attachment.object3D.getWorldPosition());
        let force = entity.body.position.vsub(pStart);
        force.normalize(); 
        force.scale(impulseAmount, force);
        entity.body.applyImpulse(force, entity.body.position);
      }, 0);

      entity.addEventListener('collide', function(e){
        console.log("hit");
      })
    });
}

if (scene.hasLoaded) init(); // change 2
else scene.addEventListener('loaded', init);

function init () {
  // any code that appends things to the scene
  scene.addEventListener('click', spawnBullet);
}

Есть ли способ, которым это можно остановить, и сфера остается неповрежденной после столкновения?

2 ответа

Решение

Прислушиваясь к click событие на сцене имеет обратный эффект, потому что вы получаете три события
- курсор выбрасывает единицу при нажатии на что-то
- target выдает один при нажатии
- холст испускает единицу (щелчок мышью, а не курсор в виде рамки - на элементе холста DOM).

Вы можете увидеть это в этом примере, щелкнуть по любому объекту на сцене и проверить консоль.


Вы можете слушать за mousedown событие, которое испускается курсором каждый раз, когда он "щелкает". Проверьте это здесь
При условии, что вы находитесь на компьютере, вы также можете прослушивать щелчок на холсте рамки. Если вы на vive тогда просто позвони shootBullet когда спусковой крючок нажат.

Проверьте это работает должным образом здесь.

Сфера не ломается, происходит то, что ваш click Обработчик событий вызывается несколько раз для каждого клика и создает сразу несколько сфер. Я не совсем уверен, почему это происходит. Один из способов обойти это, использовать AFRAME.utils.throttle предотвратить слишком быстрое создание сфер:

spawnBullet = AFRAME.utils.throttle(spawnBullet, 100);
scene.addEventListener('click', spawnBullet);

Обновление до новой версии A-Frame также может решить проблему.

Другие вопросы по тегам