我试图在scn节点内的不同材料之间进行碰撞检测。我有一个立方体,有6种不同的材料/颜色,球在立方体上。我想检测相同和不同颜色的碰撞,但不知道如何对每种材料应用不同的类别。
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)
SCNBox类根据需要自动创建SCNGeometryElementobjects以处理材料数量。在您的情况下,您将向geometry.materials添加6种不同的材质,因此您自动拥有6种不同的GeometryElements,每个方块的一侧都有一个。
从SCNPhysicsContact中,您可以获得两个物理实体之间的contact point。
然后,您可以执行Hit Test,这将为您提供Hit Test Result的数组。在这种情况下,数组将包含2个元素,意味着2个结果,一个用于立方体,一个用于球。
浏览这两个元素并确定哪个是多维数据集(通过获取结果的'节点'属性来确定节点的名称是' cube&# 39;或者' ball'当然,您需要在创建节点时设置节点的名称属性。)
现在您知道哪个是多维数据集的结果,获取结果的Geometry Index属性。使用该索引获取被球碰撞的面部颜色。
几何元素将与材质数组中的材质具有相同的顺序,例如,如果您获得了几何元素索引0,那么这是材质数组中的第一个材质,依此类推。