0
1

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 5 years have passed since last update.

【Swift Playgrounds】ARを作るPART.3「APIの概要」を読み解く

Last updated at Posted at 2019-12-07

この投稿は何か?

前回の続きです。
この投稿では、「APIの概要」ページを扱います。

コードを読む

このページは次のふたつのページで構成されています。

  • メインファイル
  • SharedCodeファイル

SharedCodeファイルは、以前のページと同様です。
ここでは主に、メインファイルを扱います。
ソースコード全体で行っていることを大まかに分類すると...

  • 3Dモデルおよびテキスト、3Dシェイプを作成してシーンに追加する
  • モデルをタップした時のハンドラを設定
  • カメライベントを設定
メインファイル
// モデルを作成します。
let lemon = Model.lemon
let snail = Model.snail
let eye = Model.eye
let foot = Model.foot

// モデルにカラースキームを適用します。
lemon.applyColor(scheme: .basic)

// シェイプを作成します。
// .m、.cm、.mmのプロパティによって、ARシーン内のオブジェクトに現実世界の単位を指定できます。
let pyramid = Model.pyramid(width: 10.cm, height: 10.cm, depth: 10.cm)
let box = Model.box(width: 1.cm, height: 10.cm, depth: 5.mm)
let torus = Model.torus(size: 30.cm, thickness: 5.cm)
let cube = Model.cube(size: 5.mm)
let cylinder = Model.cylinder(size: 10.cm, height: 30.cm)
let sphere = Model.sphere(size: 30.cm)

// 3Dテキストを作成します。
let text = Model.text("こんにちは。", elevation: 20.cm)

// シーンにモデルを追加します。
scene.add([lemon, pyramid, text, snail, eye, foot])

// タップでモデルが選択されたときのハンドラを設定します。
foot.onSelected = {
    foot.run(action: .scaleBy(1.2, duration: 1))
}

// onStartハンドラは“シーンを開始”を押した後に実行されます。
scene.setOnStartHandler {
    // アニメーションAPIを使うと、モデルでアニメーションを再生できます。
    pyramid.animate()
    snail.animate(.waggle)
    eye.animate(.lookLeft, repeats: .loop, completion: nil)
   
    // 1つのサウンドを再生します。
    lemon.play(.chord)
 
    // サウンドをループします。
    snail.play(.buzz, loops: false, completion: {
        snail.play(.frown, loops: true)
    })
}

// 距離イベントを作成します。
scene.camera.when(snail, isWithin: 10.cm, do: {
    // オプションのパラメータを指定して、モデルからテキストを読み上げます。
    snail.speak(text: "私にそのような話しかたをしないでください!", rate: 0.2, pitch: 1.76, completion: nil)
    
    // モデルで1つのアクションを実行します。
    lemon.run(action: .moveBy(x: 10.cm, y: 10.cm, z: 50.cm, duration : 5))
    
    // アクションの実行後に完了ハンドラを実行します。
    foot.run(action: .fadeTo(0.5, duration: 2), completion: {
        foot.applyColor(scheme: .tacky)
    })
    
    // シーン内のすべてのモデルにカラースキームを適用します。
    scene.applyColor(scheme: .wacky)


    // 複数のアクションを同時に実行します。
    eye.run(group: [.rotateBy(x: 0, y: 20, z: 0, duration: 5), .moveBy(x: 0, y: 20.cm, z: 0, duration: 5)])
    
    // 複数のアクションを順番に実行します。
    pyramid.run(sequence: [.scaleTo(0.2, duration: 4), .fadeTo(0.25, duration: 2)])
})

ページごとのコード量も少しずつ、多くなってきました。
いくつかに分けて、解説します。

モデルの変数

レモン、カタツムリ、目、足の3Dモデルを作成して、変数に割り当てています。
レモンのカラースキームを変更していますが、外観の変化は個人的にあまり感じられませんでした。

// モデルを作成します。
let lemon = Model.lemon
let snail = Model.snail
let eye = Model.eye
let foot = Model.foot

// モデルにカラースキームを適用します。
lemon.applyColor(scheme: .basic)

シェイプとシーン

ピラミッドの3Dモデルが初登場です。
さらに、様々な幾何学構造体の3Dモデルを作成しています。
まだまだ、いろんなモデルがありそうです。

// シェイプを作成します。
// .m、.cm、.mmのプロパティによって、ARシーン内のオブジェクトに現実世界の単位を指定できます。
let pyramid = Model.pyramid(width: 10.cm, height: 10.cm, depth: 10.cm)
let box = Model.box(width: 1.cm, height: 10.cm, depth: 5.mm)
let torus = Model.torus(size: 30.cm, thickness: 5.cm)
let cube = Model.cube(size: 5.mm)
let cylinder = Model.cylinder(size: 10.cm, height: 30.cm)
let sphere = Model.sphere(size: 30.cm)

// 3Dテキストを作成します。
let text = Model.text("こんにちは。", elevation: 20.cm)

// シーンにモデルを追加します。
scene.add([lemon, pyramid, text, snail, eye, foot])

最後に、作成したモデルやテキスト、シェイプをadd()メソッドでシーンに追加しています。
この時点では、ボックスやトーラス、キューブなどの幾何学構造モデルはシーンに追加していません。

ハンドラ

シーンが開始されたあと、モデルがタップされた時にインタラクションするようにしています。
ここでは、足がタップされたら大きくなります。

モデルがタップされたときのハンドラ
foot.onSelected = {
    foot.run(action: .scaleBy(1.2, duration: 1))
}

足モデルfootonSelectedプロパティにクロージャを割り当てています。

さらに、シーンが開始された直後に動き出すハンドラも設定しています。

  • ピラミッド、カタツムリ、目がアニメーション
  • レモンが鳴る
  • カタツムリが鳴き続ける
シーンを開始した直後のハンドラ
scene.setOnStartHandler {
    pyramid.animate()
    snail.animate(.waggle)
    eye.animate(.lookLeft, repeats: .loop, completion: nil)
   
    lemon.play(.chord)
    snail.play(.buzz, loops: false, completion: {
        snail.play(.frown, loops: true)
    })
}

animate()メソッドには、パラメータ違いによるいくつかのバラエティがあるようです。
また、これらのクロージャボディは、シーンのsetOnStartHandlerメソッドのパラメータとして渡されるような記述になっています。

距離のイベント

「簡単なシーン」ページと同様に、カメラのイベントを指定しています。
ただし、ここでは後付けクロージャ形式になっていません。

カメラとカタツムリの距離が10cm以内になると...

  • カタツムリが喋り出す
  • レモンが動く
  • 足が半透明になる
  • シーン全体のカラースキームが変わる
距離イベントを作成
scene.camera.when(snail, isWithin: 10.cm, do: {
    snail.speak(text: "私にそのような話しかたをしないで!", rate: 0.2, pitch: 1.76, completion: nil)    
    lemon.run(action: .moveBy(x: 10.cm, y: 10.cm, z: 50.cm, duration : 5))
    foot.run(action: .fadeTo(0.5, duration: 2), completion: {
        foot.applyColor(scheme: .tacky)
    })
    
    scene.applyColor(scheme: .wacky)

    eye.run(group: [.rotateBy(x: 0, y: 20, z: 0, duration: 5), 
                    .moveBy(x: 0, y: 20.cm, z: 0, duration: 5)])    
    pyramid.run(sequence: [.scaleTo(0.2, duration: 4), 
                           .fadeTo(0.25, duration: 2)])
})

コードを読んでわかったこと

  • 3Dモデルには、幾何学構造モデルがある
  • モデルがタップされた時のハンドラは、onSelectedプロパティに割り当てる
  • シーン開始時のハンドラは、setOnStartHanderメソッドに渡す

さらに...

次はいよいよ、ページ「蝶を捕まえる」です。
こちらで解説します。

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?