Home > Mobile >  Stopping an object falling through another using Physics in SceneKit
Stopping an object falling through another using Physics in SceneKit

Time:06-08

Swift 5, iOS 14

I have a box, that I give a dynamic physical body too and a plane on which I drop said box since I set the box to be affected by gravity.

I set up collision and contacts tests and detect the fact that one hits the other.

But I what I want to do is stop the box falling though the plane. Even if I turn gravity off when they collide, the stupid box keeps going...

I also tried changing the type from dynamic to static on the box, no effect.

I also tried changing the velocity of the box to zero on collision, no effect.

            box.physicsBody?.isAffectedByGravity = true
            box.physicsBody?.friction = 0
            box.physicsBody?.restitution = 1 //bounceness of the object
            box.physicsBody?.angularDamping = 1 // rotationess
            box.physicsBody = SCNPhysicsBody(type: .dynamic, shape:SCNPhysicsShape(geometry: targetGeometry, options:nil))
            box.physicsBody?.mass = 0.01
            
            box.physicsBody?.categoryBitMask = foodCategory;
            box.physicsBody?.contactTestBitMask = heroCategory;
            box.physicsBody?.collisionBitMask = 0;

And

    let planeGeo = SCNPlane(width: 8, height: 8)
    planeGeo.firstMaterial?.diffuse.contents = UIColor.blue
    planeGeo.firstMaterial?.isDoubleSided = true
    let planeNode = SCNNode(geometry: planeGeo)
    planeNode.simdPosition = SIMD3(x: 0, y: -4, z: -4)
    planeNode.eulerAngles = SCNVector3(x: GLKMathDegreesToRadians(45), y: 0, z: 0)
    
    planeNode.physicsBody?.isAffectedByGravity = false
    planeNode.physicsBody?.friction = 0
    planeNode.physicsBody?.restitution = 0 //bounceness of the object
    planeNode.physicsBody?.angularDamping = 1 // rotationess
    planeNode.physicsBody = SCNPhysicsBody(type: .static, shape:SCNPhysicsShape(geometry: planeGeo, options:nil))
    
    
    
    planeNode.physicsBody?.categoryBitMask = heroCategory;
    planeNode.physicsBody?.contactTestBitMask = foodCategory;
    planeNode.physicsBody?.collisionBitMask = 0;
    
   
    scene.rootNode.addChildNode(planeNode)

What have I missed here?

CodePudding user response:

Try to use binary notation for your Physics Categories like:

let BitmaskCollision        = Int(1 << 2)
let BitmaskCollectable      = Int(1 << 3)
let BitmaskEnemy            = Int(1 << 4)
let BitmaskSuperCollision   = Int(1 << 5)
let BitmaskWater            = Int(1 << 6)

Avoid using the 0 for the Collision Mask. Try using Int(1 << 2)

You also must use the category Bitmasks from your box within the collision detection of the plane i.Ex. like so:

planeNode.physicsBody?.collisionBitMask = BitmaskCollision | foodCategory
(example with multiple masks)

or

box.physicsBody?.collisionBitMask = heroCategory
  • Related