4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Xcode-14.1 iOS-16.0

はじめに

先日かわいいチキンを作ったのですがどうせなら AR で表示したいという欲が出てきました:smiling_imp:

SpriteKitで2D横スクロールゲームをつくろう(その1)

調べていると ARSKView というまさに AR でチキンを表示するために用意されたような View を発見しました。

これはもうやるしかない!ということで AR でチキンを表示します。

完成形はこんな感じです:chicken:

chicken

やりたいこと

やりたいことは下記。

  1. 画像マーカーを認識する
  2. 認識した画像マーカーにチキンを表示する

画像マーカー設定

下記記事を参考に画像マーカーを設定します。

  1. Assets > AR and Textures > New AR Resource Group で Group 追加
  2. マーカー用の画像を追加
  3. マーカーのサイズ指定(今回はてきとーに 15cm * 15cm で設定しました)
marker

マーカーにはちょうど手元にあったオレイカルコスの結界を使います(なんか警告出てますが気にしません)。

これでマーカーの設定は終わりです。

ARSKViewを表示する

とりあえず ARSKView を表示してみます。

  1. info.plist に「Privacy - Camera Usage Description」を追加
  2. Storyboard で ViewControllerARSKView を追加
  3. ViewControllerARSKView を接続
  4. ViewController に下記追加
    import UIKit
    import ARKit
    
    final class ViewController: UIViewController {
    
        @IBOutlet private weak var arskView: ARSKView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            arskView.presentScene(.init(size: arskView.frame.size))
            let configuration = ARWorldTrackingConfiguration()
            arskView.session.run(configuration)
        }
    }
    

これで動きます!(カメラ映るだけですが)

マーカーを認識させる

次にマーカーを認識できるようにしていきます。

以下のように ARWorldTrackingConfiguration から ARImageTrackingConfiguration に変更し ARSKViewDelegate を追加します。

arskView.delegate = self

let configuration = ARImageTrackingConfiguration()
let images = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil)
configuration.trackingImages = images!
configuration.maximumNumberOfTrackedImages = 1
arskView.session.run(configuration)

extension ViewController: ARSKViewDelegate {

    func view(_ view: ARSKView, nodeFor anchor: ARAnchor) -> SKNode? {
        print("マーカーみっけ!!!")
        return nil
    }
}

これでマーカーを認識するとコンソールに「マーカーみっけ!!!」と表示されるようになりました。

チキンを表示する

いよいよチキンを表示します。

ARSKViewDelegate の部分を下記のように修正します。

extension ViewController: ARSKViewDelegate {

    func view(_ view: ARSKView, nodeFor anchor: ARAnchor) -> SKNode? {
        let parentNode = SKNode()
        let chicken = SKSpriteNode(texture: .init(imageNamed: "c1"), size: .init(width: 32, height: 32))
        let jumpTextures: [SKTexture] = [
            .init(imageNamed: "j1"),
            .init(imageNamed: "j2")
        ]
        let action = SKAction.group([
            .animate(with: jumpTextures, timePerFrame: 0.2),
            .sequence([
                .wait(forDuration: 0.2),
                .moveBy(x: 0, y: 10, duration: 0.2),
                .moveBy(x: 0, y: -10, duration: 0.2)
            ])
        ])
        chicken.run(.repeatForever(action))
        parentNode.addChild(chicken)
        return parentNode
    }
}

view(_ view: ARSKView, nodeFor anchor: ARAnchor)SKNode を返すと指定の ARAnchor にノードが追加されるのでこれでチキンが表示できます。

parentNodechicken を add しているのはそのまま chicken を返すと ARAnchor で固定されてしまいアニメーションで動かせないためです。

参考:ARKitでつくったAR空間上に置いたSpriteKitのSKNodeをアニメーションで動かす方法

おわりに

意外とかんたんに AR でかわいいチキンの表示ができました:chicken:

50 行いかないくらいでサクッと AR が試せます!いい時代ですね:kissing_closed_eyes:

ソース全体
import UIKit
import ARKit

final class ViewController: UIViewController {

    @IBOutlet private weak var arskView: ARSKView!
    private let jumpTextures: [SKTexture] = [
        .init(imageNamed: "j1"),
        .init(imageNamed: "j2"),
    ]

    override func viewDidLoad() {
        super.viewDidLoad()

        arskView.delegate = self
        arskView.presentScene(.init(size: arskView.frame.size))
        let configuration = ARImageTrackingConfiguration()
        let images = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil)
        configuration.trackingImages = images!
        configuration.maximumNumberOfTrackedImages = 2
        arskView.session.run(configuration)
    }
}

extension ViewController: ARSKViewDelegate {

    func view(_ view: ARSKView, nodeFor anchor: ARAnchor) -> SKNode? {
        let parentNode = SKNode()
        let player = SKSpriteNode(texture: .init(imageNamed: "c1"), size: .init(width: 32, height: 32))
        let action = SKAction.group([
            .animate(with: jumpTextures, timePerFrame: 0.2),
            .sequence([
                .wait(forDuration: 0.2),
                .moveBy(x: 0, y: 10, duration: 0.2),
                .moveBy(x: 0, y: -10, duration: 0.2)
            ])
        ])
        player.run(.repeatForever(action))
        parentNode.addChild(player)
        return parentNode
    }
}

参考

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?