2016-03-22 18 views
1

SCNPhysicsContactDelegate, categoryBitMask, collisionBitMask ve fizikWorld func'in nasıl çalıştığını öğrenebilmem için basit bir Scenekit sahnesini kurmaya çalışıyorum. Ayrıca bir contactTestBitMask kurmam gerekip gerekmediğinden emin değilim.Scenekit'te Swift ile çarpışma tespitini nasıl ele alabilirim?

Kontak algılama hakkında bilgi edinmek beni uzun bir bitsel işleç yolunu ve bit maskeleme kavramını yolladı. İkili olarak eklemek eğlencelidir! Ancak, bu hala çok sisli ve ben hem SpriteKit hem de SceneKit'te bulduğum birkaç öğretici bir araya getirmeye çalışıyorum. This is the most comprehensive ama Obj-C'de ve ben Swift'e nasıl tercüme edeceğimi anlamıyorum.

İşte yarattığım şey. Herhangi bir anlayış çok takdir edilecektir. Yanlış ayarlamış olduğumu görebiliyor musun? Kırmızı haddeleme topu mavi hedefe çarptığında basit bir Print ifadesi almak istiyorum. Zemin, rampa ve hedef .statik, yuvarlanan top ise .dinamik.

Animated Gif of Scene

import UIKit 
import SceneKit 


class ViewController: UIViewController, SCNPhysicsContactDelegate { 
    //category bit masks for ball node and target node 
    // ball = 0001 -> 1 and target = 0010 ->2 
    let collisionRollingBall: Int = 1 << 0 
    let collsionTarget: Int = 1 << 1 

//declare variables 
var sceneView: SCNView! 
var cameraNode: SCNNode! 
var groundNode: SCNNode! 
var lightNode: SCNNode! 
var rampNode: SCNNode! 
var rollingBallNode: SCNNode! 
var targetNode: SCNNode! 

override func viewDidLoad() { 
    super.viewDidLoad() 
    //set up sceneview and scene. Define the physicsworld contact delegate as self 
    sceneView = SCNView(frame: self.view.frame) 
    sceneView.scene = SCNScene() 
    sceneView.scene!.physicsWorld.contactDelegate = self 
    self.view.addSubview(sceneView) 

    //add floor 
    let groundGeometry = SCNFloor() 
    groundGeometry.reflectivity = 0 
    let groundMaterial = SCNMaterial() 
    groundMaterial.diffuse.contents = UIColor.greenColor() 
    groundGeometry.materials = [groundMaterial] 
    groundNode = SCNNode(geometry: groundGeometry) 

    //add ramp 
    let rampGeometry = SCNBox(width: 4, height: 1, length: 18, chamferRadius: 0) 
    rampNode = SCNNode(geometry: rampGeometry) 
    rampNode.position = SCNVector3(x: 0, y: 2.0, z: 1.0) 
    rampNode.rotation = SCNVector4(1, 0, 0, 0.26) 

    //add rolling ball 
    let rollingBallGeometry = SCNSphere(radius: 0.5) 
    let sphereMaterial = SCNMaterial() 
    sphereMaterial.diffuse.contents = UIColor.redColor() 
    rollingBallGeometry.materials = [sphereMaterial] 
    rollingBallNode = SCNNode(geometry: rollingBallGeometry) 
    rollingBallNode.position = SCNVector3(0, 6, -6) 

    //add target box 
    let targetBoxGeometry = SCNBox(width: 4, height: 1, length: 4, chamferRadius: 0) 
    let targetMaterial = SCNMaterial() 
    targetMaterial.diffuse.contents = UIColor.blueColor() 
    targetBoxGeometry.materials = [targetMaterial] 
    targetNode = SCNNode(geometry: targetBoxGeometry) 
    targetNode.position = SCNVector3(x: 0, y: 0.5, z: 11.5) 
    targetNode.rotation = SCNVector4(-1,0,0,0.592) 

    //add a camera 
    let camera = SCNCamera() 
    self.cameraNode = SCNNode() 
    self.cameraNode.camera = camera 
    self.cameraNode.position = SCNVector3(x: 13, y: 5, z: 12) 
    let constraint = SCNLookAtConstraint(target: rampNode) 
    self.cameraNode.constraints = [constraint] 
    constraint.gimbalLockEnabled = true 

    //add a light 
    let spotLight = SCNLight() 
    spotLight.type = SCNLightTypeSpot 
    spotLight.castsShadow = true 
    spotLight.spotInnerAngle = 70.0 
    spotLight.spotOuterAngle = 90.0 
    spotLight.zFar = 500 
    lightNode = SCNNode() 
    lightNode.light = spotLight 
    lightNode.position = SCNVector3(x: 0, y: 25, z: 25) 
    lightNode.constraints = [constraint] 

    //define physcis bodies 
    let groundShape = SCNPhysicsShape(geometry: groundGeometry, options: nil) 
    let groundBody = SCNPhysicsBody(type: .Static, shape: groundShape) 
    groundNode.physicsBody = groundBody 

    let rampShape = SCNPhysicsShape(geometry: rampGeometry, options: nil) 
    let rampBody = SCNPhysicsBody(type: .Static, shape: rampShape) 
    rampNode.physicsBody = rampBody 

    let sphereShape = SCNPhysicsShape(geometry: rollingBallGeometry, options: nil) 
    let sphereBody = SCNPhysicsBody(type: .Dynamic, shape: sphereShape) 
    rollingBallNode.physicsBody?.categoryBitMask = collisionRollingBall 
    rollingBallNode.physicsBody?.collisionBitMask = collsionTarget 
    rollingBallNode.physicsBody = sphereBody 

    let targetShape = SCNPhysicsShape(geometry: targetBoxGeometry, options: nil) 
    let targetBody = SCNPhysicsBody(type: .Static, shape: targetShape) 
    targetNode.physicsBody?.categoryBitMask = collsionTarget 
    targetNode.physicsBody?.collisionBitMask = collisionRollingBall 
    targetNode.physicsBody = targetBody 

    //add nodes to view 
    sceneView.scene?.rootNode.addChildNode(groundNode) 
    sceneView.scene?.rootNode.addChildNode(rampNode) 
    sceneView.scene?.rootNode.addChildNode(rollingBallNode) 
    sceneView.scene?.rootNode.addChildNode(targetNode) 
    sceneView.scene?.rootNode.addChildNode(self.cameraNode) 
    sceneView.scene?.rootNode.addChildNode(lightNode) 

} 

func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact) { 
print("contact") 

// let contactMask = contact.nodeA.categoryBitMask | 
//contact.nodeB.categoryBitMask 

    //if contactMask == collsionTarget | collisionRollingBall { 
     // print("The ball hit the target") 
    // } 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 


} 
+1

** GÜNCELLEME: ** Sorunu çözmeyi başardım. Sahnedeki farklı düğümler için kurduğum çarpışmaBitMask'ın eksik olduğunu anladım. Sahnedeki çeşitli düğümler için daha eksiksiz bir çarpışma etkileşimi listesi tanımladım. Ayrıca, contact.nodeA.categoryBitMask'ı 'contact.nodeA.physicsBody! .categoryBitMask' olarak değiştirdim ve her şey çalıştı. Neden bunun bir fark yarattığından emin değil ama yaptı. Neden biliyor musun? – brickm

cevap

0

Ben size physicsBody hala olduğunda "catagoryBitMask" ve "collisionBitMask" değerlerini ayarlamak için çalışıyoruz çünkü temsilci işlevinde "catagoryBitMask" değerini sıfırlamak zorunda düşünüyorum sıfırdır.

rollingBallNode.physicsBody?.categoryBitMask = collisionRollingBall 
rollingBallNode.physicsBody?.collisionBitMask = collsionTarget 
rollingBallNode.physicsBody = sphereBody 

Bu 3. satırı yerleştirmeyi deneyin.

İlgili konular