2016-03-22 13 views
1

私はSCNPhysicsContactDelegate、categoryBitMask、collisionBitMask、およびphysicsWorld funcがどのように動作するかを知ることができるように、いくつかの物理を持つ簡単なScenekitシーンを設定しようとしています。私もcontactTestBitMaskを設定する必要があるかどうかはわかりません。SwiftでScenekitの衝突検出を処理するにはどうすればよいですか?

接触検出について学ぶことで、ビットワイズ演算子の長い経路とビットマスキングの概念がわかりました。バイナリで追加するのは楽しいです!しかし、これはまだまったく霧に包まれており、私はSpriteKitとSceneKitの両方で見つけたいくつかのチュートリアルをまとめてみようとしています。 This is the most comprehensiveしかし、それはObj-Cであり、Swiftにどのように翻訳するのか分かりません。

これは私が作成したものです。どんな洞察も高く評価されるだろう。あなたは私が間違って設定したものを見ることができますか?赤いローリングボールが青のターゲットに当たったときに、簡単なPrint文を出したいと思います。フロア、ランプ、ターゲットは静的ですが、ローリングボールは.dynamicです。

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

**更新:**私は問題を解決することができました。私は、シーン内の異なるノードに対して設定したcollisionBitMasksが不完全であることに気付きました。シーンのさまざまなノードの衝突の相互作用のより完全なリストを定義しました。また、 'contact.nodeA.categoryBitMask'を' contact.nodeA.physicsBody!.categoryBitMask'に変更しました。なぜそれが違いを生み出したのか分かりませんが、それはありました。なぜなのかご存知ですか? – brickm

答えて

0

私はphysicsBodyがまだあるとき、あなたは「catagoryBitMask」と「collisionBitMask」の値を設定しようとしているので、あなたがデリゲート機能に「catagoryBitMask」値をリセットするために抱えていると思いますなし。

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

3行目を先頭にしてください。

関連する問題