0

我正在学习 SceneKit,并且有以下代码在我的球撞到墙上时播放声音。

if contactNode.physicsBody?.categoryBitMask == CategoryWall {

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

这行得通,但是我只希望在球最初撞到墙上时播放声音,目前它正在沿着墙壁滚动,这会导致声音尝试重复并因此导致问题。

我尝试将 waitForCompletion 更改为 false 或 true,这没有帮助。

是否可以设置方法或属性来检查初始联系,然后在联系中断后重置?

提前致谢。

凯夫

4

2 回答 2

0

我在很多应用程序中也面临这个问题,到目前为止我发现的唯一可行的解​​决方案是使用变量在触摸之间产生一些延迟。例如:

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
   }
}

} 

是的,这是一个糟糕的解决方案,但如果没有更好的解决方案,它会起作用。

于 2020-01-14T18:20:04.867 回答
0

我通过确保仅在接触时播放影响音频并通过为声音动作设置唯一键来完成此问题来解决此问题。这确保不会有多个声音动作快速连续地添加到节点(通常在低冲击角度下看到):

  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")
   }
于 2020-04-19T17:24:02.537 回答