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