前提・実現したいこと
swiftのARkitでの開発中に衝突判定ができなくて困っています。
どなたかお助けください。。
発生している問題・エラーメッセージ
タップして出現させたノード(cube)と
平面検出後に出現させたノード(floor)が衝突しません。。
viewDidLoad内にただの平面ノード記述すると衝突するのですが
// 平面が検出されたときに呼ばれる
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) このメソッドを使って平面を作成すると衝突してくれません。
かなりググり倒したんですが、解決しないのでここで質問させて頂きました。
該当のソースコード
swift
1 2 enum CollisionBitmask: Int { 3 case cube = 1 4 case floor = 2 5 } 6 override func viewDidLoad() { 7 super.viewDidLoad() 8 9 10 // シーンを作成して登録 11 scene = SCNScene() 12 self.sceneView.scene = scene 13 // デリゲートを設定 14 sceneView.delegate = self 15 sceneView.session.delegate = self 16 //当たり判定用のデリゲート 17 scene.physicsWorld.contactDelegate = self 18 19 //sceneView.scene.physicsWorld.contactDelegate = self 20 21 // 特徴点を表示する 22 23 sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints] 24 25 // ライト追加 26 sceneView.autoenablesDefaultLighting = true; 27 28 // タップイベントハンドラの登録 29 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapView)) 30 sceneView.addGestureRecognizer(tapGesture) 31 32 // ロングプレスイベントハンドラの登録 33 let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPressView)) 34 sceneView.addGestureRecognizer(longPressGesture) 35 36// 平面検出 37 let configuration = ARWorldTrackingConfiguration() 38 configuration.planeDetection = [.horizontal, .vertical] 39 //オクルージョンの記述 40 configuration.frameSemantics = .personSegmentationWithDepth 41 sceneView.session.run(configuration) 42 43 44 45 //(タップしたら※指が離れたら。呼び出される) 46 @objc func tapView(sender: UITapGestureRecognizer) { 47 48 49 50 // タップした座標にヒットする平面を取得する 51 let location = sender.location(in: sceneView) 52 let hitTestResult = sceneView.raycastQuery(from: location, allowing: .existingPlaneGeometry, alignment: .any) 53 let results = sceneView.session.raycast(hitTestResult!) 54 if let result = results.first { 55 56 57 // Cubeを作成 58 let cube = SCNBox(width: 0.1, height: 0.2, length: 0.3, chamferRadius: 0) 59 cubeNode = SCNNode(geometry: cube) 60 cubeNode.name = "cube" 61 62 63 let boxBody = SCNPhysicsBody(type: .dynamic, shape: nil) 64 boxBody.mass = 1 65 boxBody.categoryBitMask = CollisionBitmask.cube.rawValue 66 cubeNode.physicsBody = boxBody 67 // cubeNode.position.y = 8 68 // cubeNode.rotation = SCNVector4Make(1, 1, 1, 1) 69 70 71 72 // Cubeのマテリアルを設定 73 let material = SCNMaterial() 74 material.diffuse.contents = UIColor.blue 75 material.diffuse.intensity = 0.8; 76 cubeNode.geometry?.materials = [material] 77 78 nowPosition = SCNVector3( 79 result.worldTransform.columns.3.x, 80 result.worldTransform.columns.3.y + 1, 81 result.worldTransform.columns.3.z 82 ) 83 cubeNode.position = nowPosition 84 85 xPoint = Double(nowPosition.self.x) 86 yPoint = Double(nowPosition.self.y) 87 zPoint = Double(nowPosition.self.z) 88 print("a") 89 90 // scene.rootNode.addChildNode(cubeNode) 91 sceneView.scene.rootNode.addChildNode(cubeNode) 92 93 } 94 95 } 96 97 //長押し(ロングタップしたら)呼ばれる 98 @objc func longPressView(sender: UILongPressGestureRecognizer) { 99 if sender.state == .began { 100 let location = sender.location(in: sceneView) 101 let hitTest = sceneView.hitTest(location) 102 if let result = hitTest.first { 103 if result.node.name == "cube" 104 { 105 result.node.removeFromParentNode(); 106 } 107 } 108 } 109 } 110 111} 112extension TestViewController { 113 114 115 116 117//平面。垂直面のノード生成 118 119 120 121 122 // 平面が検出されたときに呼ばれる 123 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { 124 125 guard let planeAnchor = anchor as? ARPlaneAnchor else {return()} 126 127 // 平面ジオメトリの作成 128 let planeGeometry = ARSCNPlaneGeometry(device: sceneView.device!)! 129 130 planeGeometry.update(from: planeAnchor.geometry) 131 planeGeometry.firstMaterial?.diffuse.contents = UIImage(named: "buleWireFrame") 132 //planeGeometry.firstMaterial?.diffuse.contents = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5) 133 // 平面ノードの作成 134 let planeNode = SCNNode() 135 planeNode.geometry = planeGeometry 136 137 planeNode.name = "flatNode" 138 let floorBody = SCNPhysicsBody(type: .static, shape: nil) 139 floorBody.contactTestBitMask = CollisionBitmask.cube.rawValue 140 floorBody.collisionBitMask = CollisionBitmask.cube.rawValue 141 floorBody.categoryBitMask = CollisionBitmask.floor.rawValue 142 planeNode.physicsBody = floorBody 143 144 print("b") 145 // ノードの追加 146 node.addChildNode(planeNode) 147 148 149 //sceneView.scene.rootNode.addChildNode(planeNode) 150 151 152 } 153 154 // 平面の形状が更新されたときに呼ばれる 155 func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { 156 guard let planeAnchor = anchor as? ARPlaneAnchor else {return} 157 guard let planeGeometry = node.childNodes.first!.geometry as? ARSCNPlaneGeometry else {return} 158 159 // 平面の形状をアップデート 160 planeGeometry.update(from: planeAnchor.geometry) 161 162 print("c") 163 } 164 }
回答1件
あなたの回答
tips
プレビュー