命中检测过程是指在视图上去一点,找出3D中的哪个对象位于视图上这个点的下方。实际上就是要回答:我点了谁?
在对一个SceneKit视图进行命中检测时,会得到一个SCNHitTestResult对象的数组,其中描述了找到的对象,以及该对象的相关信息。
下面这段代码可以让你点击的地方短暂的发亮一下:
- import UIKit
- import SceneKit
- import SpriteKit
-
- class SceneKitViewController: UIViewController {
-
- override func viewDidLoad() {
- super.viewDidLoad()
- let sceneView = self.view as! SCNView
- sceneView.backgroundColor = UIColor.grayColor()
- //sceneView.allowsCameraControl = true
- // 添加场景
- let sceneOne = SCNScene()
- sceneView.scene = sceneOne
- // 添加照相机 并指明水平和垂直视角都是45度
- let cameraOne = SCNCamera()
- cameraOne.xFov = 45
- cameraOne.yFov = 45
- // 将照相机附加到节点
- let cameraNode = SCNNode()
- cameraNode.camera = cameraOne
- cameraNode.position = SCNVector3(0,0,20)
- sceneOne.rootNode.addChildNode(cameraNode)
- // 添加3D对象
- let capsuleOne = SCNCapsule(capRadius: 2.5,height: 10)
- let capsuleNodeOne = SCNNode(geometry: capsuleOne)
- capsuleNodeOne.position = SCNVector3(0,0)
- sceneOne.rootNode.addChildNode(capsuleNodeOne)
- // 添加环境光源
- let ambientLight = SCNLight()
- ambientLight.type = SCNLightTypeAmbient
- ambientLight.color = UIColor(white: 0.25,alpha: 1.0)
- let ambientNodeOne = SCNNode()
- ambientNodeOne.light = ambientLight
- sceneOne.rootNode.addChildNode(ambientNodeOne)
- // 添加泛光源
- let omniLight = SCNLight()
- omniLight.type = SCNLightTypeOmni
- omniLight.color = UIColor(white:1.0,alpha: 1.0)
- let omniNodeOne = SCNNode()
- omniNodeOne.light = omniLight
- omniNodeOne.position = SCNVector3(-5,8,5)
- sceneOne.rootNode.addChildNode(omniNodeOne)
- // 为场景中的内容实现动画
- let moveUpAndDownAnimation = CABasicAnimation(keyPath: "position")
- moveUpAndDownAnimation.byValue = NSValue(SCNVector3:SCNVector3(0,5,0))
- // 在最后加速和减速,而不是机械弹跳
- moveUpAndDownAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaSEOut)
- // 在末端自动返回
- moveUpAndDownAnimation.autoreverses = true
- // 动画无限次循环
- moveUpAndDownAnimation.repeatCount = Float.infinity
- moveUpAndDownAnimation.duration = 2
- // 添加到一个节点
- capsuleNodeOne.addAnimation(moveUpAndDownAnimation,forKey: "upAndDown")
- // 创建文本几何体
- let text3D = SCNText(string: "BlaBlaBla",extrusionDepth: 0.3)
- text3D.font = UIFont.systemFontOfSize(2)
- let textNode = SCNNode(geometry: text3D)
- textNode.position = SCNVector3(-5,6,0)
- capsuleNodeOne.addChildNode(textNode)
- // 合并动画
- let rotateAnimation = CABasicAnimation(keyPath: "eulerAngles")
- rotateAnimation.byValue = NSValue(SCNVector3: SCNVector3(x: Float(0),y: Float(M_PI*2),z: Float(0)))
- rotateAnimation.repeatCount = Float.infinity
- rotateAnimation.duration = 4
- textNode.addAnimation(rotateAnimation,forKey: "rotation")
- // 质感和纹理
- let redMetallicMaterial = SCNMaterial()
- redMetallicMaterial.diffuse.contents = UIColor.grayColor()
- redMetallicMaterial.specular.contents = UIColor.whiteColor()
- redMetallicMaterial.shininess = 1
- capsuleOne.materials = [redMetallicMaterial]
- // 文字纹理
- let noiseTexture = SKTexture(noiseWithSmoothness:0.25,size:CGSize(width: 512,height: 512),grayscale:true)
- let noiseMaterial = SCNMaterial()
- noiseMaterial.diffuse.contents = noiseTexture
- text3D.materials = [noiseMaterial]
- // 法向贴图
- let noiseNormalMapTexture = noiseTexture.textureByGeneratingNormalMapWithSmoothness(0.1,contrast: 1)
- redMetallicMaterial.normal.contents = noiseNormalMapTexture
- // 命中检测
- let tapRecognizerOne = UITapGestureRecognizer(target: self,action: "tapped:")
- sceneView.addGestureRecognizer(tapRecognizerOne)
- // 启动用户交互
- sceneView.userInteractionEnabled = true
-
- }
-
- func tapped(tapRecognizer:UITapGestureRecognizer){
- if tapRecognizer.state == UIGestureRecognizerState.Ended{
- let sceneView = self.view as! SCNView
- let hits = sceneView.hitTest(tapRecognizer.locationInView(tapRecognizer.view),options: nil) as [SCNHitTestResult]
-
- for hit in hits {
- if let theMaterial = (hit.node.geometry?.materials[0]) as SCNMaterial? {
- let highLightAnimation = CABasicAnimation(keyPath: "contents")
- highLightAnimation.fromValue = UIColor.blackColor()
- highLightAnimation.toValue = UIColor.yellowColor()
- highLightAnimation.autoreverses = true
- highLightAnimation.repeatCount = 0
- highLightAnimation.duration = 0.3
-
- theMaterial.emission.addAnimation(highLightAnimation,forKey: "highLight")
- }
- }
- }
- }
-
-
- }