skip to Main Content

I am creating a game where I am shooting a projectile that I want to stop once I detect it hits a target, I have setup the correct category bit masks and contact bit mask. I do not have a collision bit mask as I do not want a collision, I want a full stop.

My code is simple on the contact detection:

func didBegin(_ contact: SKPhysicsContact) {
    switch (contact.bodyA.node, contact.bodyB.node) {
    case (let dart as DartNode, let point as PointNode), (let point as PointNode, let dart as DartNode):
        dart.physicsBody?.isDynamic = false
    case (_, _):
        break
    }
}

Sometimes, honestly like 30% of the time it seems like setting isDynamic is not actually causing the projectile to stop at the contact point and the physics engine continues to apply force for just a bit more. See the attached image where I show an example where the projectile is stop exactly at the point of contact vs where it goes beyond the contact point deeper into my physics body.

Is there something I am missing here and is there a better way to pause a node on contact?

2

Answers


  1. I can only make assumptions without screenshots and much code, bu try to remove eventual actions and use the velocity property:

     dart.physicsBody?.velocity = CGVector.zero
    

    Also, if the dart is moving fast, you might want to take a look at usesPreciseCollisionDetection, docs.

    Login or Signup to reply.
  2. without knowing many of the details, I had an idea that you could give these nodes names and then use the enumerateChildNodes(with: name) method to reference them when the contact occurs to stop their movement.

    dart.name = "dart" or dartNode.name = "dart"

    enumerateChildNodes(withName: "dart") { node, stop in 
        node.removeAllActions 
    }
    

    you could also create a physics category identified as none and then give your nodes a collision bit mask with the category none to be certain it cannot collide with anything

    enum PhysicsCategories: UInt32 {
        case dart = 1
        case point = 2
        case none = 4 
    }
    

    then explicitly say

    dart.physicsBody.collisionbitmask = PhysicsCategory.none.rawValue

    Also try the .isPaused method on your Scene

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search