I'm trying to get collision detection between different materials within an scn node. I have a cube with 6 different materials/ colors and balls coming at the cube. I'd like to detect same and different colored collisions but don't know how to apply different categories to each material.
import UIKit
import SceneKit
class GameViewController: UIViewController, SCNPhysicsContactDelegate {
Can I create categories to assign to different sides of the cube later?
let ballCategory = 0
let cubeCategory = 1
let ballGreen = 2
let ballRed = 3
let ballBlue = 4
let ballYellow = 5
let ballPurple = 6
let ballOrange = 7
let cubeGreen = 8
let cubeRed = 9
let cubeBlue = 10
let cubeYellow = 11
let cubePurple = 12
let cubeOrange = 13
setup stuff
var scnView: SCNView!
var scnScene = SCNScene()
var cameraNode: SCNNode!
var cubeNode = SCNNode()
var ball = SCNNode()
var randomColor: UIColor?
var timer = Timer()
override func viewDidLoad() {
super.viewDidLoad()
scnScene.physicsWorld.contactDelegate = self
scnView = self.view as? SCNView
view.scene = scnScene
view.isPlaying = true
}
setupView()
setupScene()
setupCamera()
spawnCube()
}
Will physics world did begin contact work?
func physicsWorld(world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
print("Physics called")
if (contact.nodeA == cubeNode || contact.nodeA == ball) && (contact.nodeB == cubeNode || contact.nodeB == ball) {
print("contact")
}
if (contact.nodeA.physicsBody!.categoryBitMask == 2 && contact.nodeB.physicsBody!.categoryBitMask == 8) || (contact.nodeB.physicsBody!.categoryBitMask == 2 && contact.nodeA.physicsBody!.categoryBitMask == 8) {
print("green contact")
}
if (contact.nodeA.physicsBody!.categoryBitMask == 3 && contact.nodeB.physicsBody!.categoryBitMask == 9) || (contact.nodeB.physicsBody!.categoryBitMask == 3 && contact.nodeA.physicsBody!.categoryBitMask == 9) {
print("green contact")
}
if (contact.nodeA.physicsBody!.categoryBitMask == 4 && contact.nodeB.physicsBody!.categoryBitMask == 10) || (contact.nodeB.physicsBody!.categoryBitMask == 4 && contact.nodeA.physicsBody!.categoryBitMask == 10) {
print("green contact")
}
if (contact.nodeA.physicsBody!.categoryBitMask == 5 && contact.nodeB.physicsBody!.categoryBitMask == 11) || (contact.nodeB.physicsBody!.categoryBitMask == 5 && contact.nodeA.physicsBody!.categoryBitMask == 11) {
print("green contact")
}
if (contact.nodeA.physicsBody!.categoryBitMask == 6 && contact.nodeB.physicsBody!.categoryBitMask == 12) || (contact.nodeB.physicsBody!.categoryBitMask == 6 && contact.nodeA.physicsBody!.categoryBitMask == 12) {
print("green contact")
}
if (contact.nodeA.physicsBody!.categoryBitMask == 7 && contact.nodeB.physicsBody!.categoryBitMask == 13) || (contact.nodeB.physicsBody!.categoryBitMask == 7 && contact.nodeA.physicsBody!.categoryBitMask == 13) {
print("green contact")
}
}
func setupView() {
scnView = self.view as! SCNView
scnView.showsStatistics = false
scnView.allowsCameraControl = false
scnView.autoenablesDefaultLighting = true
}
func setupScene() {
scnScene = SCNScene()
scnView.scene = scnScene
scnScene.background.contents = UIColor.black
}
func setupCamera() {
cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(x: 0, y: 0, z: 10)
scnScene.rootNode.addChildNode(cameraNode)
}
Cube setup, I'm getting an error when I try to add a category to the different sides/ materials
func spawnCube() {
var geometry:SCNGeometry
geometry = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0.05)
cubeNode = SCNNode(geometry: geometry)
let greenMaterial = SCNMaterial()
greenMaterial.diffuse.contents = UIColor.green
greenMaterial.locksAmbientWithDiffuse = true
let redMaterial = SCNMaterial()
redMaterial.diffuse.contents = UIColor.red
redMaterial.locksAmbientWithDiffuse = true
let blueMaterial = SCNMaterial()
blueMaterial.diffuse.contents = UIColor.blue
blueMaterial.locksAmbientWithDiffuse = true
let yellowMaterial = SCNMaterial()
yellowMaterial.diffuse.contents = UIColor.yellow
yellowMaterial.locksAmbientWithDiffuse = true
let purpleMaterial = SCNMaterial()
purpleMaterial.diffuse.contents = UIColor.purple
purpleMaterial.locksAmbientWithDiffuse = true
let orangeMaterial = SCNMaterial()
orangeMaterial.diffuse.contents = UIColor.orange
orangeMaterial.locksAmbientWithDiffuse = true
geometry.materials = [greenMaterial, redMaterial, blueMaterial,
yellowMaterial, purpleMaterial, orangeMaterial]
cubeNode.physicsBody?.mass = 10000
cubeNode.physicsBody?.restitution = 0
cubeNode.physicsBody?.damping = 0
cubeNode.physicsBody = SCNPhysicsBody.kinematic()
cubeNode.physicsBody?.categoryBitMask = Int(cubeCategory)
cubeNode.physicsBody?.contactTestBitMask = Int(ballCategory)
cubeNode.physicsBody?.isAffectedByGravity = false
cubeNode.position = SCNVector3(x: 0, y: 0, z: 0)
scnScene.rootNode.addChildNode(cubeNode)
}
Ball setup, I'm also getting an error when I try to add a different category to different ball colors
func spawnBall() {
var geometry:SCNGeometry
geometry = SCNSphere(radius: 0.25)
let ball = SCNNode(geometry: geometry)
let randomNumberForColor = Int(arc4random_uniform(6))
if randomNumberForColor == 1 {
randomColor = UIColor.green
}
if randomNumberForColor == 2 {
randomColor = UIColor.red
}
if randomNumberForColor == 3 {
randomColor = UIColor.blue
}
if randomNumberForColor == 4 {
randomColor = UIColor.yellow
}
if randomNumberForColor == 5 {
randomColor = UIColor.purple
}
if randomNumberForColor == 6 {
randomColor = UIColor.orange
}
if randomNumberForColor == nil {
randomColor = UIColor.green
}
let greenMaterial = SCNMaterial()
greenMaterial.diffuse.contents = randomColor
greenMaterial.locksAmbientWithDiffuse = true;
geometry.materials = [greenMaterial]
ball.physicsBody?.mass = 0.00001
ball.physicsBody?.restitution = 1
ball.physicsBody?.damping = 0
ball.physicsBody = SCNPhysicsBody.dynamic()
ball.physicsBody?.categoryBitMask = Int(ballCategory)
ball.physicsBody?.contactTestBitMask = Int(cubeCategory)
ball.physicsBody?.isAffectedByGravity = false
randomX()
randomY()
randomZ()
ball.position = SCNVector3(x: Float(randomNumX!), y: Float(randomNumY!), z: Float(randomNumZ!))
scnScene.rootNode.addChildNode(ball)
let force = SCNVector3(x: Float(-randomNumX!)/2, y: Float(-randomNumY!)/2, z: Float(-randomNumZ!)/2)
ball.physicsBody?.applyForce(force, at: cubeNode.position, asImpulse: true)
}
func randomX() {
randomNumX = Int(arc4random_uniform(10)) - 5
}
func randomY() {
randomNumY = Int(arc4random_uniform(20)) - 10
}
func randomZ() {
randomNumZ = Int(arc4random_uniform(10)) - 5
}
}
Maybe there's a way to simplify this and just detect ball and cube collisions with a qualifier of matching color?
Thanks!