Swift Playgroundsで学ぶiOSプログラミング

「物理学体」と「物理学場」を設定して物理現象をシミュレーション

文●柴田文彦 編集●吉田ヒロ

2018年08月01日 17時00分

画面に映ったノードにタッチすることで「フォース」を働かせる

 これでSceneKitによる仮装の3D世界も、それなりのリアリティを持つものになりました。しかし、このままでは、プログラムを起動した直後に始まる最初の動きが落ち着くと、再び何も動かない静寂の世界に戻ってしまいます。

 そこで、外部から物理学体に力を加えて、動かす方法を考えてみましょう。物理学体には、前回のようなアニメーション機能による強制的な動作を与えることもできます。しかしここでは、あくまでも物理学的な力を加えて、物理学の法則に従った動きをさせてみることにします。もちろん上で加えたバネ力も有効ですが、最初から存在する空気抵抗のような力、物理学体同士のの摩擦力、あるいは衝突した際の反発力のような力も、すべてまとめて作用します。

 前回にも利用したタップジェスチャーの認識機能を使って、タップされたノードに物理学的な力を加えてみることにします。まずは、viewDidLoadメソッドの中に、タップジェスチャーのレコグナイザーを記述します。この部分は前回のものとまったく同じです。

タップしたノードにフォースを与えられるように、前回も使ったジェスチャーレコグナイザーを導入します。前回とまったく同じようにviewDidLoadメソッドの中に記述し、タップが検出されたら同じビューコントローラー内のsceneTappedメソッドを呼び出すようにします

 あとは、タップジェスチャーが認識された際に呼ばれるsceneTappedメソッドの中身を記述するだけです。ここでも、タッチが発生した画面の座標からノードを割り出す部分は前回と同じです。今回は、3次元ベクトル(SCNVector3)によって、フォースと呼ばれるデータを作成します。この中身は乱数で決めることにしました。x軸とy軸の成分は-25.0〜25.0の範囲、y軸成分は0〜50.0の範囲としています。y軸にマイナス方向がないのは、床に押し付ける力を加えても面白くないからです。タップされたノードの中のどこを叩くのかも、3次元ベクトルで指定します。中心よりもずれた位置を叩けば、回転力が加わるわけです。その値も、0.0〜1.0の範囲で乱数で決めることにしました。

タップを検出すると呼び出されるsceneTappedメソッド内では、前回と同様にまずタップの座標からノードを割り出します。そのノードには乱数によって値を決めた3次元ベクトルによって、強さと方向、位置の異なる衝撃力を与えています。ノードの種類は区別していませんが、ダイナミックなものだけに作用するので問題ありません

 このプログラムを動かすと、床の上や上方に配置したノードがバネ力によって床の中央に寄り集まるところまでは上の例と同じです。しかし、そこからどれかのノードをタップすると、そのノードにランダムな方向の力がランダムな位置に加わります。それによって、寄り集まったノードをかき混ぜるような動きを与えることができます。

このプログラムを動かすと、そのままでは上の例と何も変わりません。しかし、画面に投影されたノードをタップするとそのノードにだけランダムな力が加わります。各ノードには物理学体が設定してあるので、接したり衝突したりしたノードには力が伝達され、つられて動きます。これでそれなりのリアリティーのある仮想3D世界が実現できました

 もちろん、しばらく放っておくと、バネのような力で引き寄せられたノードは、再び床の中央に寄り集まります。

次回の予定

 今回は、シーンの中に最初から存在する重力によって、物理学体を設定したノードを動かしたり、新たな物理学場を設定して、自然界には存在しないような力でノードを引き寄せたりする動きを試してみました。これでSceneKitについてもだいぶ勘所がつかめたのではないかと思います。次回は再びARKitに戻って、この経験を拡張現実の世界で生かしてみる予定です。

mobileASCII.jp TOPページへ

mobile ASCII

Access Rankingアクセスランキング