Scenekit: runAction только при первом контакте

Я изучаю SceneKit, и у меня есть следующий код, который воспроизводит звук, когда мой мяч ударяется о стену.

if contactNode.physicsBody?.categoryBitMask == CategoryWall {

        let hitSound = sounds["bump"]!
        ballNode.runAction(SCNAction.playAudio(hitSound, waitForCompletion: true))
        }

Это работает, однако я хочу воспроизвести звук только тогда, когда мяч сначала ударяется о стену, в настоящее время он катится по стене, и это заставляет звук повторяться и, следовательно, вызывает проблемы.

Я попытался изменить waitForCompletion на false или true, это не помогло.

Есть ли метод или атрибут, который можно настроить для проверки первоначального контакта, а затем сброса после разрыва контакта?

заранее спасибо.

Кев


person Lynxbci    schedule 05.01.2020    source источник
comment
поиск касаний начался   -  person Sourav Sachdeva    schedule 10.01.2020


Ответы (2)


Я сталкиваюсь с этой проблемой и во многих своих приложениях, и единственное работающее решение, которое я нашел до сих пор, — это использование переменной для создания некоторой задержки между касаниями. Например:

var touched = false

func physicsWorld(){
touched = true
if !touched{
   let hitSound = sounds["bump"]!
      ballNode.runAction(SCNAction.playAudio(hitSound, waitForCompletion: true))
   }
   DispatchQueue.main.asyncAfter(deadline: .now() + 0.1){
      touched = false
   }
}

} 

Да, это ужасное решение, но если нет лучшего решения, оно работает.

person Jakub    schedule 14.01.2020

Я решил эту проблему, убедившись, что звук удара воспроизводится только при контакте, и до завершения, установив уникальный ключ для звукового действия. Это гарантирует, что к узлу не будут добавлены несколько звуковых действий в быстрой последовательности (обычно наблюдаемые при малых углах удара):

  func playSound(node:SCNNode, name:String) {
     //Where [sounds] are pre-loaded SFX
     let sound = sounds[name]
     if (node.action(forKey: "playSFX") != nil) {
       return
     }
     let action = SCNAction.playAudio(sound!, waitForCompletion: true)
     node.runAction(action, forKey: "playSFX")
   }
person rswayz    schedule 19.04.2020