画面に映ったノードにタッチすることで「フォース」を働かせる
これでSceneKitによる仮装の3D世界も、それなりのリアリティを持つものになりました。しかし、このままでは、プログラムを起動した直後に始まる最初の動きが落ち着くと、再び何も動かない静寂の世界に戻ってしまいます。
そこで、外部から物理学体に力を加えて、動かす方法を考えてみましょう。物理学体には、前回のようなアニメーション機能による強制的な動作を与えることもできます。しかしここでは、あくまでも物理学的な力を加えて、物理学の法則に従った動きをさせてみることにします。もちろん上で加えたバネ力も有効ですが、最初から存在する空気抵抗のような力、物理学体同士のの摩擦力、あるいは衝突した際の反発力のような力も、すべてまとめて作用します。
前回にも利用したタップジェスチャーの認識機能を使って、タップされたノードに物理学的な力を加えてみることにします。まずは、viewDidLoadメソッドの中に、タップジェスチャーのレコグナイザーを記述します。この部分は前回のものとまったく同じです。
あとは、タップジェスチャーが認識された際に呼ばれるsceneTappedメソッドの中身を記述するだけです。ここでも、タッチが発生した画面の座標からノードを割り出す部分は前回と同じです。今回は、3次元ベクトル(SCNVector3)によって、フォースと呼ばれるデータを作成します。この中身は乱数で決めることにしました。x軸とy軸の成分は-25.0〜25.0の範囲、y軸成分は0〜50.0の範囲としています。y軸にマイナス方向がないのは、床に押し付ける力を加えても面白くないからです。タップされたノードの中のどこを叩くのかも、3次元ベクトルで指定します。中心よりもずれた位置を叩けば、回転力が加わるわけです。その値も、0.0〜1.0の範囲で乱数で決めることにしました。
このプログラムを動かすと、床の上や上方に配置したノードがバネ力によって床の中央に寄り集まるところまでは上の例と同じです。しかし、そこからどれかのノードをタップすると、そのノードにランダムな方向の力がランダムな位置に加わります。それによって、寄り集まったノードをかき混ぜるような動きを与えることができます。
もちろん、しばらく放っておくと、バネのような力で引き寄せられたノードは、再び床の中央に寄り集まります。
次回の予定
今回は、シーンの中に最初から存在する重力によって、物理学体を設定したノードを動かしたり、新たな物理学場を設定して、自然界には存在しないような力でノードを引き寄せたりする動きを試してみました。これでSceneKitについてもだいぶ勘所がつかめたのではないかと思います。次回は再びARKitに戻って、この経験を拡張現実の世界で生かしてみる予定です。