ios - SceneKit:如何在没有碰撞的情况下检测接触

标签 ios objective-c macos swift scenekit

我正在寻找最佳方式(性能方面)来检测 SceneKit 物理世界中两个不碰撞(不相互反弹)的物体之间的接触。

我看到 SpriteKit 有一个 contactTestBitMask 和一个用于物理体的 collisionBitMask 而 SceneKit 只有后者。因此,当对象在 SceneKit 中发生接触时,必须有另一种首选方式来获得通知。我想在每个对象的每个帧中调用 contactTestBetweenBody:andBody:options: 不是最好的方法吗?

更新 在 iOS 9.0 中,Apple 已将 contactTestBitMask 添加到 SCNPhysicsBody。所以这个问题很快就会过时。

最佳答案

这个问题值得一个完整的教程。简而言之,每个物理体都有一个categoryBitMask和collisionBitMask。

类别位掩码 这是代表 body 的位。

碰撞位掩码 这是代表哪些物体与之碰撞的位。

默认情况下(当指定一个 physicsBody 时)所有物体都会发生碰撞,但 kinematicBody 除外,它的行为很特殊。物体不会与之碰撞。但不要混淆,手动移动时(例如用手指拖动)它可能会与其他对象发生碰撞。

如何处理!!!

分配你的 body ,无论是静态的还是动态的。在那里分配类别和碰撞掩码。如果掩码匹配,它们就会发生碰撞。举个例子怎么样!

这些物体相互碰撞

bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;

bodyA.physicsBody.collisionBitMask = 8;
bodyB.physicsBody.collisionBitMask = 4;

它们不会碰撞

bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;

bodyA.physicsBody.collisionBitMask = 0;
bodyB.physicsBody.collisionBitMask = 0;

注意到我使用了 2 的幂的类别。这是因为 contactDelegate 使用按位 AND 进行比较。如果您不明白,请按位阅读。这真的会有帮助。

这些物体在没有物理的情况下发生碰撞

示例:您有一个英雄穿过幽灵,您想知道它发生时没有任何一个受到影响。比如互相弹跳。

bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;

bodyA.physicsBody.collisionBitMask = 0;
bodyB.physicsBody.collisionBitMask = 0;

所以设计了下面的代码,让bodyA(你的英雄)贯穿bodyB(幽灵)。

bodyB.physicsField.categoryBitMask = 4

注意到上面是一个physicsField.catagoryBitMask。它被指定为 4,以便与 bodyA 匹配。

let collisionField = SCNPhysicsField.customFieldWithEvaluationBlock(){ 
    (_, _, _, _, _) in 
    WHAT U WANT TO DO ON CONTACT
}

bodyB.physicsField = collisionField

不幸的是,physicsField 不是您的几何形状。如果将 physicsField 属性 usesEllipsoidalExtent 设置为“true/yes”,它的默认值是其边界框或球体/椭圆形的形状

效果区域可以使用 physicsFields 的 halfExtent 属性来改变,就像这样......

bodyB.physicsField.halfExtent = SCNVector3Make(.5, .5, .5)

上面的代码会将大小为 (2, 2, 2) 的框的字段扩展为 (2.5, 2.5, 2.5)。

编辑:如果它们仍然发生碰撞,请尝试从 bodyB 中移除 physicsbody(这将从节点中移除所有物理模拟)。只要类别和碰撞位掩码分配正确,我认为这不会成为问题。

这是我能找到的最好的方法。在 Apple 文档的支持下,所有编码都来 self 的头脑,因此可能不完全正确,但我希望这对您有所帮助!

关于ios - SceneKit:如何在没有碰撞的情况下检测接触,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25065933/

相关文章:

ios - UIProgressView 自定义最大值

ios - uitableview 默认图像显示不同大小?

objective-c - 如何收听屏幕截图

regex - R 正则表达式中的变音匹配

ios - 删除 TabGroup 选项卡标题并仅在适用于 iOS 的 Appcelerator 应用程序上显示图标

objective-c - iOS:卸载和弹出 View Controller

objective-c - 为什么我的 iOS5 核心数据项目提示需要 iOS5?

objective-c - 在 Cocoa 中使用 XML 编写游戏关卡

ios - 可以使用带有 itms-services 的自签名 SSL 证书

ios - 在 stackview 中以编程方式定位 View 、标签、 ImageView 的问题