2017-09-13 56 views
1

我试图在scn节点内的不同材质之间进行碰撞检测。我有一个有6种不同材料/颜色的立方体,并且球体来自立方体。我想要检测相同和不同颜色的碰撞,但不知道如何对每种材质应用不同的类别。如何在scn节点内的不同材质上碰撞检测

import UIKit 
import SceneKit 

class GameViewController: UIViewController, SCNPhysicsContactDelegate { 

我可以创建类别以便稍后分配给多维数据集的不同侧面吗?

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 

设置的东西

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() 

} 

威尔物理世界确实开始接触工作?

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) 

} 

立方设置,我得到一个错误,当我尝试将类别添加到不同的侧面/材料

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) 
} 

球的设置,我也得到一个错误,当我尝试添加不同的类别,以不同颜色的球

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 

} 

}

也许有简化这个办法只用匹配颜色的限定符来检测球和立方体的碰撞?

谢谢!

+0

当你发现一个接触,为什么不把球的颜色和脸的颜色进行比较?这是你的事后? –

+0

是的,你有推荐的实现吗? – spapp

回答

0

SCNBox类根据需要自动创建SCNGeometryElementobjects来处理材质数量。在你的情况下,你需要为geometry.materials添加6种不同的材质,所以你会自动拥有6种不同的GeometryElement,一个用于立方体的每一面。

从SCNPhysicsContact,你可以得到两个物理实体之间的contact point

随着这一点,你可以做一个Hit Test,它会给你一个Hit Test Result的阵列。在这种情况下,数组将有2个元素,即2个结果,一个用于立方体,另一个用于球。

通过这两个元素并确定哪一个是多维数据集(通过获取结果的“节点”属性并查看该节点的名称是'多维数据集'还是'球'),当然,您需要在创建节点时设置节点的名称属性)。

现在您知道哪一个是Cube的结果,请获取结果的Geometry Index属性。使用该索引来获取被球碰撞的面的颜色。

几何元素将与材料数组中的材质具有相同的顺序,例如,如果您的几何元素索引为0,即材质数组中的第一种材质,则以此类推。