[swift] scenekit / 追加したdaeモデルをタップして追加、選択、消去

scenekit / 追加したdaeモデルをタップして追加、選択、消去するコードは以下の通り

モデルを追加するときに”object”という名前をノードに付与し、hittestでヒットした時に名前を確認。

もし”object”であれば、モデルを赤くし、名前は”selected”に変更

さらに”selected”モデルをタップすると、フェードアウトでノードを消去する

何も無いところをタップすると上からタップしたところをベースに上から降ってくる。

ただし、hittestでHitしたところの座標を拾っているので、床をタップしたときに限る。

 

daeモデルを追加する時の注意点はこちらを参照のこと

class GameViewController: UIViewController,UIGestureRecognizerDelegate {

    //MARK: Property
    
    let ball = "art.scnassets/Ball.dae"
    
    var scene = SCNScene()
    var scnView = SCNView()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupScene(scene: scene)

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        
        tapGesture.delegate = self
        scnView.addGestureRecognizer(tapGesture)

    }

    @objc
    func handleTap(_ gestureRecognize: UIGestureRecognizer) {
        
        let scnView = self.view as! SCNView
        
        let p = gestureRecognize.location(in: scnView)

        let hitResults = scnView.hitTest(p, options: [:])

        if hitResults.count > 0 {
            
            // retrieved the first clicked object
            let result = hitResults[0]
            let material = result.node.geometry!.firstMaterial!
            
            if result.node.name == "object"{
                
                material.emission.contents = UIColor.red
                result.node.name = "selected"
                
            }else if(result.node.name == "selected"){
                
                result.node.runAction(SCNAction.sequence([
                    SCNAction.fadeOut(duration: 0.5),
                    SCNAction.removeFromParentNode()
                    ]))
                
            }else{
                // sceneView上のタップ座標のどこに出現させるかを指定
                let position = SCNVector3Make(
                    result.worldCoordinates.x,
                    result.worldCoordinates.y + 4,
                    result.worldCoordinates.z
                )
                scene.rootNode.addChildNode(createObject(position: position, restitution: 0.1, filepath: ball))
            }
            
        }else{
            scene.rootNode.addChildNode(createObject(position: SCNVector3Make(-1.5, y, 0), restitution: 0.1, filepath: ball))
        }
    }

    
    //daeモデルを生成
    func createObject(position:SCNVector3, restitution:CGFloat,filepath:String) -> SCNNode {
        let scene = SCNScene(named: filepath)
        let node: SCNNode = scene!.rootNode.childNodes[0]
        let aModelShape = SCNPhysicsShape(node: node, options: nil)
        let physicsBody = SCNPhysicsBody(type: .dynamic, shape: aModelShape)
        physicsBody.restitution = restitution
        node.physicsBody = physicsBody
        node.position = position
        node.name = "object"
        
        return node
    }

func setupScene(scene:SCNScene) {
        
        //カメラ追加
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(x: 0, y: 1, z: 15)
        scene.rootNode.addChildNode(cameraNode)
        
        //床を作成
        let floor = SCNFloor()
        floor.reflectivity = 0.25
        let floorNode = SCNNode(geometry: floor)
        let floorShape = SCNPhysicsShape(geometry: floor, options: nil)
        let floorBody = SCNPhysicsBody(type: .static, shape: floorShape)
        floorNode.physicsBody = floorBody
        scene.rootNode.addChildNode(floorNode)
        
        // create and add a light to the scene
        let lightNode = SCNNode()
        lightNode.light = SCNLight()
        lightNode.light!.type = .omni
        lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
        scene.rootNode.addChildNode(lightNode)
        
        // create and add an ambient light to the scene
        let ambientLightNode = SCNNode()
        ambientLightNode.light = SCNLight()
        ambientLightNode.light!.type = .ambient
        ambientLightNode.light!.color = UIColor.darkGray
        scene.rootNode.addChildNode(ambientLightNode)
    }


}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です