Я создал два узла: сферу и прямоугольник:
var sphere = SCNNode(geometry: SCNSphere(radius: 0.005))
//I get the box node from scn file
let boxScene = SCNScene(named: "art.scnassets/world.scn")!
var boxNode: SCNNode?
Я хочу, чтобы два узла или физика взаимодействовали, поэтому я создал категорию для categoryBitMask
и contactTestBitMask
:
struct CollisionCategory: OptionSet {
let rawValue: Int
static let box = CollisionCategory(rawValue: 1)
static let sphere = CollisionCategory(rawValue: 2)
}
Здесь я устанавливаю узел блока как физическое тело:
self.boxScene.rootNode.enumerateChildNodes { (node, _) in
if node.name == "box" {
boxNode = node
let boxBodyShape = SCNPhysicsShape(geometry: SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0.1), options: nil)
let physicsBody = SCNPhysicsBody(type: .static, shape: boxBodyShape)
boxNode!.physicsBody = physicsBody
boxNode!.physicsBody?.categoryBitMask = CollisionCategory.box.rawValue
boxNode!.physicsBody?.contactTestBitMask = CollisionCategory.sphere.rawValue
boxNode!.physicsBody?.collisionBitMask = boxNode!.physicsBody!.contactTestBitMask
}
}
Здесь я устанавливаю узел сферы в функции рендеринга, который вы можете перемещать по виду:
func setUpSphere() {
let sphereBodySphere = SCNPhysicsShape(geometry: SCNSphere(radius: 0.005))
let physicsBody = SCNPhysicsBody(type: .kinematic, shape: sphereBodySphere)
sphere.physicsBody = physicsBody
sphere.physicsBody?.categoryBitMask = CollisionCategory.sphere.rawValue
sphere.physicsBody?.contactTestBitMask = CollisionCategory.box.rawValue
sphere.geometry?.firstMaterial?.diffuse.contents = UIColor.blue
sphere.physicsBody?.collisionBitMask = sphere.physicsBody!.contactTestBitMask
previousPoint = currentPosition
}
///It Adds a sphere and changes his position
func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
guard let pointOfView = sceneView.pointOfView else { return }
let mat = pointOfView.transform
let dir = SCNVector3(-1 * mat.m31, -1 * mat.m32, -1 * mat.m33)
let currentPosition = pointOfView.position + (dir * 0.185)
if buttonPressed {
if let previousPoint = previousPoint {
sphere.position = currentPosition
sceneView.scene.rootNode.addChildNode(sphere)
}
}
}
Я добавил протокол SCNPhysicsContactDelegate
в ViewController и установил в ViewDidLoad ():
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
sceneView.scene.physicsWorld.contactDelegate = self
///I correctly see the shapes of the sphere and the box physics bodies using
sceneView.debugOptions = .showPhysicsShapes
createBox()
setUpSphere()
sceneView.scene = boxScene
sceneView.scene.physicsWorld.contactDelegate = self
}
Затем я добавил эту функцию:
func physicsWorld(_ world: SCNPhysicsWorld, didEnd contact: SCNPhysicsContact) {
print("Collision!")
}
Вот что происходит.
Когда два узла сталкиваются, ничего не происходит, поэтому я не могу знать, касаются ли эти два тела.Может быть проблема в .kinematic, .static или в функции render ()?Я шаг за шагом следовал различным учебникам о столкновениях в ARKit: Учебник 1 , Учебник 2 .Я понятия не имею, почему это не работает, как ожидалось.Что-то не так в моем коде?
Скачать код ссылки на файл: https://ufile.io/20sla