问题描述
我正在寻找最好的方法(性能方面)来检测两个不会在SceneKit物理世界中发生碰撞(不互相反弹)的物体之间的接触。
I'm looking for the best way (performace-wise) to detect contact between two objects that do not collide (not bounce off each other) in a SceneKit physics world.
我看到SpriteKit有物理实体的 contactTestBitMask
和 collisionBitMask
,而SceneKit只有后者。因此,当对象在SceneKit中有联系时,必须有另一种首选方式来获得通知。我想在每个对象的每个帧中调用 contactTestBetweenBody:andBody:options:
不是最好的方法吗?
I saw that SpriteKit has a contactTestBitMask
and a collisionBitMask
for physics bodies while SceneKit only has the latter. So there must to be another preferred way to get notified when objects have contact in SceneKit. I guess that calling contactTestBetweenBody:andBody:options:
in each frame for each object is not the best way to do it?
更新
在iOS 9.0中,Apple已将 contactTestBitMask
添加到 SCNPhysicsBody
。所以这个问题很快就会过时。
UPDATEWith iOS 9.0, Apple has added contactTestBitMask
to SCNPhysicsBody
. So this question will become obsolete soon.
推荐答案
这个问题需要一个完整的教程。简而言之,每个物理主体都有一个categoryBitMask和collisionBitMask。
This question deserves a full tutorial. In short, each physics body has a categoryBitMask and collisionBitMask.
categoryBitMask
这是代表正文的位。
categoryBitMaskThis is the bit that represents the body.
collisionBitMask
这是表示哪些实体与之碰撞的位。
collisionBitMaskThis is the bit that represents which bodies collide with it.
默认情况下(当指定了physicsBody时),所有实体都会与kinematicBody异常碰撞,后者表现特殊。物体不会与它发生碰撞。但是不要混淆,它可以在手动移动时与其他物体碰撞(例如用手指拖动)。
By default (when assigned a physicsBody) all bodies collide with the exception of a kinematicBody, which act special. Objects don't collide with it. But don't get confused, it can collide with other objects when manually moved (such as by dragging it with a finger).
如何处理!! !
指定您的身体是静态还是动态。分配类别和碰撞掩码。如果面具匹配则会发生碰撞。一个例子怎么样!
Assign your bodies whether it be static or dynamic. Assign there category and collision mask. If the mask match up they collide. How about an example!
这些机构相互碰撞
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进行比较。如果您不理解,请按位阅读。这真的会有所帮助。
Noticed I used categories by power of two. This is because the contactDelegate uses bitwise AND to compare. Read up on bitwise if you don't understand. It will really help.
这些身体在没有物理的情况下发生碰撞
示例:你有一个运行的英雄通过鬼魂你想要知道它发生在没有任何一个受影响的情况下。比如互相反弹。
EXAMPLE: You have a hero that runs through a ghost and you want to know that it happened without either one being effected. Such as bouncing off each other.
bodyA.physicsBody.categoryBitMask = 4;
bodyB.physicsBody.categoryBitMask = 8;
bodyA.physicsBody.collisionBitMask = 0;
bodyB.physicsBody.collisionBitMask = 0;
因此,以下代码的设计使bodyA(你的英雄)穿过bodyB(幽灵)。
So the following code is designed so that bodyA(your hero) runs through bodyB(ghost).
bodyB.physicsField.categoryBitMask = 4
注意到上面是physicsField.catagoryBitMask。它被赋予一个4,以便它与bodyA匹配。
Noticed that the above is a physicsField.catagoryBitMask. It is assigned a 4 so that it matches up with bodyA.
let collisionField = SCNPhysicsField.customFieldWithEvaluationBlock(){
(_, _, _, _, _) in
WHAT U WANT TO DO ON CONTACT
}
bodyB.physicsField = collisionField
不幸的是,physicsField不是几何体的形状。如果将physicsField属性usesEllipsoidalExtent设置为true / yes,则默认为其边界框或球体/椭圆形的形状
The physicsField is not the shape of your geometry unfortunately. Its default is the shape of its bounding box or sphere/elliptical if you set the physicsField property usesEllipsoidalExtent to "true/yes"
可以使用以下方法更改效果区域physicsFields halfExtent属性如此......
The area of effect can be changed using the physicsFields halfExtent property like so...
bodyB.physicsField.halfExtent = SCNVector3Make(.5, .5, .5)
以上将把(2,2,2)大小的方框字段扩展为(2.5 ,2.5,2.5)。
The above will extend the field of a box the size of (2, 2, 2) to (2.5, 2.5, 2.5).
编辑:如果它们仍然发生碰撞,请尝试从bodyB中删除物理体(这将从节点中删除所有物理模拟)。只要正确分配了catagory和碰撞位掩码,我认为这不会是一个问题。
EDIT: If they still collide, try removing the physicsbody from bodyB (this will remove all physics simulation from the node). I don't think it will be a problem as long as the catagory and collision bitmask are assigned properly.
这是我能找到的最佳方法。在Apple文档的支持下,所有编码都来自我的头脑,所以可能不完全正确,但我希望这会有所帮助!
This is the best method I could find. All coding is from my head, with the support of Apple docs, so may not be exactly right but I hope this helps!
这篇关于SceneKit:如何在没有碰撞的情况下检测接触的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!