Search code examples
swiftsprite-kitcollision-detectionskphysicsbodyskphysicscontact

Swift/SpriteKit - Collisions and Objects


I have a class called Item, and inside there is an instance variable called itemNode which is of type SKSpriteNode. In my GameScene class, when I create an instance of Item I create a physics body that is given to the Item's itemNode. In my collision detection system, when my character's physics body collides with the itemNode's physics body, I want to preform a function on the Item object whose node's physics body just collided. However, the collision system only returns to physics body. How do I access the Item object given only the physics body of the node?


Solution

  • The SKPhyicsBody class has a node property which points to the SKNode instance it is attached to.

    Your collision detection code can look something like this:

    func didBeginContact(contact: SKPhysicsContact) {
    
        var item: SKSpriteNode
        var character: SKSpriteNode
    
        //Change this on the basis of the order of your categoryBitMask values
        if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
        {
            item = contact.bodyA.node as SKSpriteNode
            character = contact.bodyB.node as SKSpriteNode
        }
        else
        {
            item = contact.bodyB.node as SKSpriteNode
            character = contact.bodyA.node as SKSpriteNode
        }
    
        //Perform necessary operations on item and character
    }
    

    EDIT: In order to get access to the Item instance that declares the node, you will have to store a variable within the node which points to the Item instance. For this, you can either subclass SKSpriteNode and include a property, or use the userData property of SKNode

    Subclassing:

    //New Class
    class ItemNode: SKSpriteNode {
    
        static var itemInstance
    }
    
    //In the Item class declare the itemNode using this class
    let itemNode = ItemNode()
    itemNode.itemInstance = self
    

    UserData property:

    item.userData = NSMutableDictionary(object: self, forKey: "ItemInstance"))