swift - 调用 contactTestBetweenBody 时出现奇怪的 EXC_BAD_ACCESS

标签 swift scenekit

我在场景工具包中创建了一个 3D 场景,该场景包含一个被无形墙壁包围的区域,我想将物理对象以这样一种方式转换到该区域中,即它们一旦进入就无法逃脱。我想通过以下方式实现此目的:

  1. 创建墙对象
  2. 创建一个整齐地安装在墙内的“固化剂”
  3. 将每个对象的 isInScene 变量设置为 false
  4. 将它们朝固化剂的模糊方向抛出
  5. 每次更新时,如果一个物体接触固化器但没有接触墙壁,我会更改它的碰撞 mask 以包括墙壁并将 isInScene 设置为 true,这样我就不必检查

这通常看起来工作得很好,但每隔一段时间(遗憾的是经常)我会莫名其妙地收到 EXC_BAD_ACCESS 错误。有问题的方法似乎是 contactTestBetweenBody,我用它来确定对象何时在正常碰撞检测关闭时接触墙壁或凝固器。这是必要的,以防止对象简单地从墙对象的外部弹回。

这里有一小段代码来说明。顺便说一句,“对象”是一种结构,它保留对节点的引用以及其他有用的细节:

if let solid = solidifier?.physicsBody, let wall = walls?.physicsBody {
    let world = scene.physicsWorld
    for i in 0 ..< objects.count {
        if objects[i].isInScene == false, let body = objects[i].node.physicsBody {
            let contactSolidifier = world.contactTestBetweenBody(body, andBody: solid, options: nil)
            if contactSolidifier != nil {
                let contactWall = world.contactTestBetweenBody(body, andBody: wall, options: nil)
                if contactWall == nil {
                    objects[i].isInScene = true
                    body.collisionBitMask = CollisionMask.allSolids.rawValue
                }
            }
        }
    }
}

最佳答案

我找到了一个更好的解决方案来解决我出于某种原因根本没有想到的问题。忘掉这种将物体保持在视野中的荒谬而复杂的方法吧。相反,只需创建您想要保留对象的区域并反转其面方向和法线即可。

我没有意识到的是,SceneKit 也在碰撞检测中使用了背面剔除,所以如果一个物理对象撞到一个从里到外的对象的外部,它将干净利落地通过。

我仍然有兴趣知道错误访问错误的原因,因为接触测试方法很有用,我将来可能想将它们用于其他原因。

关于swift - 调用 contactTestBetweenBody 时出现奇怪的 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32103018/

相关文章:

当 PMCalendar 点击或打开时,ios swift 关闭键盘

ios - 如何知道第三方编写的代码是否在发布时运行

ios - SecKeyRef 到 base64 并 swift 返回

IOS 11 - 当另一个 pin 落后时,MKMapView pin 对话框不可点击

ios - 我可以观察 SCNView 的相机变换吗?

swift - 如何计算两点之间的预计到达时间 - Swift/谷歌地图

ios - 用几何体放置 SCNNode

ios - 如何知道节点是否在屏幕中可见或在 SceneKit 中不可见?

ios - SceneKit - 音频在我第一次播放声音时导致 cxa_throw 延迟

cocoapods - SCNScene 加载来自 pod 的纹理