将类别,冲突和接触位掩码分配给代码中的引用节点

时间:2016-08-03 07:42:02

标签: swift xcode collision-detection scenekit

我有一个基于关卡的游戏,因此我使用Xcode场景编辑器进行关卡创建,但我遇到了检测对象之间碰撞的麻烦,这些对象是在不同的场景中创建的,并在游戏场景中作为参考节点拖动。

似乎如果我尝试创建一个对象的物理主体,它在我创建它的.scn文件中用作参考节点,那么物理主体不会被引用到游戏场景中的节点,但是直接在场景编辑器中创建的属性是。

如果我尝试通过代码设置实际上是参考节点的每个节点的物理体,它会设置它(物理体不是nil),但是没有检测到碰撞。

这是我设置物理实体的代码:

    // player (I want to be notified when player collides with any walls)
    playerNode = level1Scene.rootNode.childNodeWithName("playerNode", recursively: true)!
    playerNode.physicsBody = SCNPhysicsBody(type: .Dynamic, shape: nil)
    playerNode.physicsBody?.affectedByGravity = false
    playerNode.physicsBody?.categoryBitMask = PhysicsCategory.Player.rawValue
    playerNode.physicsBody?.collisionBitMask = PhysicsCategory.Wall.rawValue
    playerNode.physicsBody?.contactTestBitMask = PhysicsCategory.Wall.rawValue

    //wall from separate .scn file
    let wallScene = SCNScene(named: "wallObject.scn")
    let wall = wallScene!.rootNode.childNodeWithName("wall", recursively: true)!
    wall.physicsBody = SCNPhysicsBody(type: .Kinematic, shape: nil)
    wall.physicsBody?.categoryBitMask = PhysicsCategory.Wall.rawValue
    wall.physicsBody?.collisionBitMask = PhysicsCategory.Player.rawValue
    wall.physicsBody?.contactTestBitMask = PhysicsCategory.Player.rawValue

    // walls that are reference nodes of the wall and are located in game scene 
    let wall2 = level1Scene.rootNode.childNodeWithName("wallObject reference", recursively: true)!
    wall2.physicsBody = SCNPhysicsBody(type: .Kinematic, shape: nil)
    wall2.physicsBody?.categoryBitMask = PhysicsCategory.Wall.rawValue
    wall2.physicsBody?.collisionBitMask = PhysicsCategory.Player.rawValue
    wall2.physicsBody?.contactTestBitMask = PhysicsCategory.Player.rawValue
    print(wall2.physicsBody!) // prints <SCNPhysicsBody: 0x7fe5f9dc75a0>

我没有联系任何联系人,也没有联系任何墙壁的玩家身体碰撞。我已经将该类符合SCNPhysicsContactDelegate协议:

extension GameViewController: SCNPhysicsContactDelegate {
    func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact) {
        playerNode.physicsBody?.velocity = SCNVector3Zero
        print("player and wall collided")
    }
}

并将联系人委托设置为我的游戏场景:

level1Scene.physicsWorld.contactDelegate = self

我一直试图让它工作两天,但没有成功。当我使用Sprite Kit时,我几乎总能找到有关我的问题的相关帖子,即使在发布我的问题时,我也会得到答案。但是Scene Kit并不像我想的那样流行,我找不到任何东西。

如果您确实知道我错在哪里或者如何在代码中检测到碰撞,请告诉我。

1 个答案:

答案 0 :(得分:1)

我根据您发布的代码松散地拼凑了一个示例,唯一的“问题”是它工作,因为联系委托被成功调用。在这种情况下,玩家几何体是SceneKit太空飞船,而wall2是添加到另一个场景中的SCNBox,然后从Finder拖入船舶场景。我已经把重力包括在内了,所以这艘船就落在了墙上。

对象是否互相反弹,只是你的联系代表没有被调用?或者对象是否相互通过。我也想知道你如何移动玩家对象以引起联系?

List<String> ls=new ArrayList<String>();

        for(int i=0;i<=Integer.MAX_VALUE-1;i++)
            ls.add(Integer.toString(i));

String array[]=ls.toArray(new String[ls.size()]);