본글은 ARKit 동영상 강의를 기반으로 작성한 글입니다. 출처는 아래에서 확인할 수 있습니다.
오역이나 잘못된 정보에 대한 수정은 언제든지 환영합니다 :)
- sceneView 에 tapGestureRecognizer 적용
탭할때마다 평면에 물체를 추가할 것이므로 sceneView 에 tapGestureRecognizer 적용해줘야함
private func registerGestureRecognizers() {let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapped))self.sceneView.addGestureRecognizer(tapGestureRecognizer)}
2. tapped(recognizer:) 함수 작성
parameter
로 받은UIGestureRecognizer
를 통해 view 와 사용자가 탭한 위치를 얻어냄.
let sceneView = recognizer.view as! ARSCNViewlet touchLocation = recognizer.location(in: sceneView)
hitTest(_:types:)
를 통해[ARHitTestResult]
반환
hitTest(_:types:)
는 탭한 위치와 대응되는 물체나 AR anchor을 찾아서 반환.
let hitTestResult = sceneView.hitTest(touchLocation, types: .existingPlaneUsingExtent)
cf) hitTest(_:types:) — Searches for real-world objects or AR anchors in the captured camera image corresponding to a point in the SceneKit view.
types
— The types of hit-test result to search for.
existingPlaneUsingExtent
— A plane anchor already in the scene (detected with the planeDetection
option), respecting the plane's limited size.
- 만약
hitTest
를 통해 얻어낸hitResult
가empty
가 아니라면addBox(hitResult:)
함수 실행
if !hitTestResult.isEmpty {guard let hitResult = hitTestResult.first else {return}addBox(hitResult :hitResult)}
3. addBox(hitResult :) 함수 작성
- 박스 모양의 노드를 만듦
let boxGeometry = SCNBox(width: 0.2, height: 0.2, length: 0.1, chamferRadius: 0)let material = SCNMaterial()material.diffuse.contents = UIColor.redboxGeometry.materials = [material]let boxNode = SCNNode(geometry: boxGeometry)
- 노드의
position
지정
boxNode.position = SCNVector3(hitResult.worldTransform.columns.3.x,hitResult.worldTransform.columns.3.y + Float(boxGeometry.height/2), hitResult.worldTransform.columns.3.z)
넘겨받은 hitResult 는 많은 속성을 가지고 있는데 그 중 worldTransform.columns통해 현실에 대응하는 x, y, z 좌표를 알 수 있음Float(boxGeometry.height/2)
를 더해준 이유는 boxNode의 center y 좌표가 hitResult.worldTransform.columns.3.y
가 된다면 평면에서 반만큼 내려가 보이기 때문
sceneView
에 적용
self.sceneView.scene.rootNode.addChildNode(boxNode)