ARオブジェクトの座標を操る方法チートシート


# カメラの50cm前に置く

![0.gif](https://qiita-image-store.s3.amazonaws.com/0/111366/f8db2965-fd23-bbba-bf31-8cc71ef33a03.gif)

```swift
guard let camera = sceneView.pointOfView else {
    return
}
let cameraPos = SCNVector3Make(0, 0, -0.5)
let position = camera.convertPosition(cameraPos, to: nil)
boxNode.position = position
```


# スクリーンのタップした位置の50cm前に置く

![2.gif](https://qiita-image-store.s3.amazonaws.com/0/111366/0665e856-16c2-0849-493d-0619caf5c3cd.gif)


```swift
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let point = touches.first?.location(in: sceneView) else {
        return
    }
    let infrontOfCamera = SCNVector3(x: 0, y: 0, z: -0.5)
    
    guard let cameraNode = sceneView.pointOfView else { return }
    let pointInWorld = cameraNode.convertPosition(infrontOfCamera, to: nil)
    
    var screenPos = sceneView.projectPoint(pointInWorld)
    
    screenPos.x = Float(point.x)
    screenPos.y = Float(point.y)
    
    let finalPosition = sceneView.unprojectPoint(screenPos)
    boxNode.position = finalPosition
}
```

# タップして平面、垂直面に置く

|水平面|垂直面|
|:-:|:-:|
|![GIFイメージ-79E879DA7D94-1.gif](https://qiita-image-store.s3.amazonaws.com/0/111366/0ea5b1b9-d196-d85d-6936-1515e207c828.gif)|![GIFイメージ-B53791B867A3-1.gif](https://qiita-image-store.s3.amazonaws.com/0/111366/129898ed-77a2-e4b9-f42f-46ac5a6e3b42.gif)|

## configuration
```swift
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = [.horizontal, .vertical]
```

## touchesBegan
```swift
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let location = touches.first?.location(in: sceneView),
        let horizontalHit = sceneView.hitTest(
            location,
            types: .existingPlane
            ).first else {
                return
    }
    let column3: simd_float4 = horizontalHit.worldTransform.columns.3
    let position = SCNVector3(column3.x, column3.y, column3.z)
    boxNode.position = position
    sceneView.scene.rootNode.addChildNode(boxNode)
}
```

# 任意の方向を向かせる

例：カメラの方向を向かせる

![4.gif](https://qiita-image-store.s3.amazonaws.com/0/111366/3e1a9483-6996-489e-3661-ff60ed5d8f34.gif)


```swift
guard let camera = sceneView.pointOfView else {
    return
}
boxNode.look(at: camera.position)
```

# カメラと同じ方向を向かせる

![5.gif](https://qiita-image-store.s3.amazonaws.com/0/111366/b1310174-5a87-98c9-95ea-44ee5eef681e.gif)


```swift
guard let camera = sceneView.pointOfView else {
    return
}
boxNode.eulerAngles = camera.eulerAngles
```

# カメラと同じ高さに置く

![1.gif](https://qiita-image-store.s3.amazonaws.com/0/111366/1856a208-f4e6-b4a0-1175-303f0070864a.gif)


```swift
guard let camera = sceneView.pointOfView else {
    return
}
let cameraPos = SCNVector3Make(0, 0, -0.5)
var position = camera.convertPosition(cameraPos, to: nil)
position.y = camera.position.y // ここ
boxNode.position = position
```

# カメラから発射する

![6.gif](https://qiita-image-store.s3.amazonaws.com/0/111366/33b954b2-2a89-b411-2151-6d373d3291e6.gif)

```swift
private func shoot(){
    guard let camera = sceneView.pointOfView else {
       return
    }
    boxNode.position = camera.position
    
    let targetPosCamera = SCNVector3Make(0, 0, -2)
    let target = camera.convertPosition(targetPosCamera, to: nil)
    let action = SCNAction.move(to: target, duration: 1)
    boxNode.runAction(action)
}
```

# カメラの前に物体をホールド

![7.gif](https://qiita-image-store.s3.amazonaws.com/0/111366/2492a951-c7a9-95b7-0bc2-3f0aa67aab95.gif)


```swift
extension PracticeViewController: ARSCNViewDelegate {
    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
        // このフラグをボタン等で切り替える
        if holding {
            guard let camera = sceneView.pointOfView else {
                return
            }
            let cameraPos = SCNVector3Make(0, 0, -0.5)
            let position = camera.convertPosition(cameraPos, to: nil)
            boxNode.position = position
        }
    }
}
```

# サンプルコード

サンプルコードはARKit-EmperorのPracticeにあります！

https://github.com/kboy-silvergym/ARKit-Emperor