【Swift】SpriteKitの使い方。物理運動の抵抗力を発生させて動きをスローにする。(Swift 2.2、XCode 7.3)

2020年6月16日

Drag Fieldとは

本記事では、SKFieldNodeの「Drag Field(以下、抗力ノード)」について説明する。

Drag FIeld

 

抗力ノードとは、物理ボディの動きに対する抵抗力を発生させるノードである。例えば、ボールを水槽の中に落としたとき、空気中を落下するよりもゆっくりと落下していく。これはボールに対する浮力と抵抗力が働くためである。

ちなみにDrag Fieldの「Drag」は「抗力」という意味。ドラッグ&ドロップの「ドラッグ」と勘違いしそうな名前だ。

抵抗力のイメージ

抗力ノードを使ってみる

実際に抗力ノードをシーンに配置して物理ボディを落下させてみよう。以降の手順を行う前のXcodeプロジェクトをGitHubに置いたので、試してみる方はご利用下さい。⇒「テスト用プロジェクト

事前準備ではボールをシーンに配置しておいた。

事前準備

 

下図赤枠のSKSファイルを選択してシーンエディタを開く。黄緑枠のオブジェクトライブラリボタンを押して部品一覧を表示し、ドラッグ&ドロップで「Drag Field」をシーンに配置する(紫矢印)。

黄枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Nameに「drag」、Parentに「center_point」、Category Maskに「1」を入力する。Enabledのチェックは入れたままにする。

Drag Fieldをシーンに配置する。

 

黒ボールの画像を選択、下図赤枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Field Maskに「1」を入力する。

抗力ノードのCategory Maskと、物理ボディのField Maskのビットマスクが同じなので、ボールは抗力ノードの物理的効果を受けるようになる。
⇒「ビットマスクとは

Field Maskに1を設定する

 

TestScene.swiftのtouchesBeganメソッドを以下のコードに変更する。画面がタップされたら重力でボールが落下するようにした。

 

以下は実際のプレイ動画。左側は抗力ノードを無効にしたもので、右側は有効にしたもの。右側は抗力ノードの抵抗力により通常よりボールがゆっくり落下した。

落下開始から一定時間ごとのボールの位置を横並びにして加速を確認してみよう。1秒を15フレームに分割して観測した。

下図は左側動画(抗力ノードを無効)の0.13秒(2フレーム)ごと落下位置。ボールが加速していることが分かる。

spritekit_drag_field_no_gravity_prot

 

下図は右側動画(抗力ノードを有効)の0.33秒(5フレーム)ごとの落下位置。移動開始直後以外は加速していないことが分かる。

これにより、水中での落下と同じように、抗力ノードの抵抗によって物理ボディの落下速度がすぐに一定になることが明らかとなった。

spritekit_drag_field_enable_true

 

ソースコードで実装する

シーンエディタではなく、ソースコードで抗力ノードを実装する場合は以下のコードのようにする。試してみる場合は、先ほどシーンエディタで追加した抗力ノードを削除してから行うこと。

 

設定項目

抗力ノードのアトリビュートインスペクタの設定項目は、概ね「Liner Gravity Field(以下、線形重力ノード)」と同じなので、そちらを参照されたし。

Drag Fieldのアトリビュートインスペクタ

 

線形重力ノードの説明と異なる項目を説明する。

Strength

物理ボディの運動に対する抵抗力の強さを設定する。あくまで抵抗力であって、運動せずに止まっている物理ボディを引き寄せたり、遠ざけたりする力は働かない。0は抵抗無し。マイナスにすると訳の分からない動きをする。

なお、SKActionのmoveメソッドなどの移動のアニメーションには抵抗力は発生しない。

以下の動画は、左側がStrength「1」、右側がStrength「10」の動画

 

Falloff

物理的効果の減衰率を設定する。抗力ノードから距離が離れると抵抗力が弱くなるということ。

抗力ノードから見て物理ボディがどこにいても、抵抗力は物理ボディの進行方向の逆向きに働く。例えば、下図のように抗力ノードを通り過ぎた直後のボールへの抵抗力は離れた位置よりも強いが、下に向かって強い抵抗力が働くわけではなく、進行方向の逆方向に抵抗力が働く。

抵抗力の減衰のイメージ

 

以下の動画は左側がFalloff「0」、右側がFalloff「0.8」の動画。右側は出だしは速いが抗力ノードに近づくにつれ減速し、抗力ノードを過ぎると加速した。

 

以下の動画は、Falloffは「0.8」に設定したままで、画面左右端にボールを追加し同時に落下させたもの。左右のボールは抗力ノードから少し離れて落下するため、中央のボールよりも早く地面に着地する。