Reputation: 91
I'm making a Space Shooter game on Scene Kit and I want the asteroids to explode when the ship gets contact with them, I don't want them to collide, I just want to know when they contact each other.
The problem is that I don't know how to implement a collision detection when the ship intersects the asteroid. Like for example, I want Xcode to log "COLLIDED" when they actually get contact with each other.
I already added the categoryBitMask
and the collisionBitMask
for both objects. So, how could I achieve this? By the way, I'm doing everything on Swift.
Upvotes: 2
Views: 3168
Reputation: 35
I got this to work with a much simpler answer.
On the node you want things to fall through, set the physics mass to a very small number:
ship.physicsBody.mass = 0.00000000000001;
Upvotes: 1
Reputation: 91
At the end I figured out how to solve this.
First I added the categoryBitMask
and the collisionBitMask
for both objects, the spaceship and the asteroids.
ship.physicsBody?.categoryBitMask = 2
asteroid.physicsBody?.categoryBitMask = 4
ship.physicsBody?.collisionBitMask = 4
ball.physicsBody?.collisionBitMask = 2
Then I gave a dynamicBody()
to both of them.
ship.physicsBody = SCNPhysicsBody.dynamicBody()
asteroid.physicsBody = SCNPhysicsBody.dynamicBody()
Then I added a NSTimer
to help me with the contact detection to update each 0.1 seconds to see if there is a contact.
override func viewDidLoad()
{
NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "checkContact", userInfo: nil, repeats: true)
}
func checkContact()
{
if (self.scene.physicsWorld.contactTestBetweenBody(ship.physicsBody, andBody: asteroid.physicsBody, options: nil) != nil)
{
println("CONTACT!")
}
}
I didn't needed to add the SCNPhysicsContactDelegate
to my view, but is better to add it to be sure there are no syntax problems or warnings.
And that's it!
NOTE: It's important to add a dynamicBody()
or staticBody()
to our 3D objects, otherwise it won't have a contact. And it's important to add the dynamicBody()
or staticBody()
to our 3D objects BEFORE we add them as a child to our scene.
Hope this helps someone!
Upvotes: -2
Reputation: 126117
SceneKit doesn't offer an option for separating contact detection from collision resolution for dynamic bodies. (If one of your bodies is a kinematic body, it won't have collisions resolved against it, but it won't be movable through physics either.) File a feature request?
However, it sounds like your use case is compatible with collision resolution — because the asteroids are exploding, you don't need to care about the effects of the collision on an asteroid (just remove it from the scene and replace it with explosion VFX, smaller asteroids, space slug, whatever). If the ship is meant to survive the collision and you don't want it to be affected by the collision, just set the relative masses of the ship and asteroid so that the asteroid won't impart significant momentum.
To do things when a collision occurs, you need to set a contact delegate on your scene's physics world. In whatever class is serving as your contact delegate, implement the didBeginContact
method to be notified when a collision occurs.
In that method, you'll need to look at the contact's nodeA
and nodeB
to find out what categories of bodies collided (and which is which). Once you know that, e.g., nodeA
is a ship and nodeB
is an asteroid (or vice versa), you can kill the asteroid, update your score, etc.
Upvotes: 2