ARKitでジェスチャーを使ってオブジェクトを拡大縮小、回転する


一度物体をAR空間に置いたときに、その物体を調整したい時があると思います。

そんなときに使える、指のジェスチャーを使った、物体を操るための実装を紹介します。

ピンチインアウトで拡大縮小

UIPinchGestureRecognizerを実装

viewDidLoadなどでgestureをaddします。

// scale gesture
let pinch = UIPinchGestureRecognizer(
    target: self,
    action: #selector(type(of: self).scenePinchGesture(_:))
)
pinch.delegate = self
sceneView.addGestureRecognizer(pinch)

ジェスチャーで呼ばれるメソッドを定義

@objc func scenePinchGesture(_ recognizer: UIPinchGestureRecognizer) {
    if recognizer.state == .began {
        lastGestureScale = 1
    }

    let newGestureScale: Float = Float(recognizer.scale)

    // ここで直前のscaleとのdiffぶんだけ取得しときます
    let diff = newGestureScale - lastGestureScale

    let currentScale = boxNode.scale

    // diff分だけscaleを変化させる。1は1倍、1.2は1.2倍の大きさになります。
    boxNode.scale = SCNVector3Make(
        currentScale.x * (1 + diff),
        currentScale.y * (1 + diff),
        currentScale.z * (1 + diff)
    )
    // 保存しとく
    lastGestureScale = newGestureScale
}

回転

UIRotationGestureRecognizerを定義

// rotate gesture
let rotaion = UIRotationGestureRecognizer(
    target: self,
    action: #selector(type(of: self).sceneRotateGesture(_:))
)
rotaion.delegate = self
sceneView.addGestureRecognizer(rotaion)

ジェスチャーで呼ばれるメソッドを定義

@objc func sceneRotateGesture(_ recognizer: UIRotationGestureRecognizer) {
    let newGestureRotation = Float(recognizer.rotation)

    if recognizer.state == .began {
        lastGestureRotation = 0
    }
    // 前回とのdiffを取得
    let diff = newGestureRotation - lastGestureRotation

    // 今回はオイラーアングルのyを取るため、y軸中心の回転をさせます。
    let eulerY = boxNode.eulerAngles.y
    boxNode.eulerAngles.y = eulerY - diff

    lastGestureRotation = newGestureRotation
}

まとめ

  • UIPinchGestureRecognizerを使って物体を指で拡大縮小しよう
  • UIRotationGestureRecognizerを使って物体を指で回転させよう

サンプルコード

https://github.com/kboy-silvergym/ARKit-Emperor のGestureのところを確認してください!