【Swift】SpriteKitの使い方。SKFieldNodeでノードに直線方向の加速度を発生させる。(Swift 2.2、XCode 7.3)

2020年6月16日

Linear Gravity Fieldとは

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

Linear Gravity Field

 

SKFieldNodeとは、バネ運動や乱気流など様々な物理的効果を物理ボディに与えるノードである。線形重力ノードはSKFieldNodeの一種で、物理ボディに直線方向の加速度を与えるノードである。

線形重力フィールドのイメージ

 

線形重力ノードを使ってみる

実際に線形重力ノードをシーンに配置して鳥ノードを移動してみよう。以降の手順を行う前のXcodeプロジェクトをGitHubに置いたので、試してみる方はご利用下さい。⇒「テスト用プロジェクト

事前準備ではシーンに3匹の鳥ノードを配置しておいた。この時点では鳥ノードをタップしても何も起きない。

 

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

黄枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Strengthに「-9.8」、Category Maskに「1」を入力する。

LInear Gravity Fieldをシーンに配置する

 

青鳥の画像を選択、赤枠のアトリビュートインスペクタボタンを押して設定画面を表示する。

設定項目の「Field Mask」を線形重力ノードのカテゴリマスクと同じにすると、このノードが加速するようになる。

しかし、今回はField Maskに「2」を設定しておいて、シミュレーターを起動後の画面タップでField Maskを変更するよう次でコーディングする。茶鳥、赤鳥も同じ「2」に設定する。

鳥ノードのFieldBItMaskを設定する

 

TestScene.swiftのtouchesBeganメソッドを以下のコードに変更する。

鳥ノードのフィールドマスクを「1」に変更して線形重力ノードの物理的効果を受けるようにした。

 

以下は実際のプレイ動画。

Strengthに「-9.8」を設定したのは、地球の重力加速度の動きと同じにするためである。これは、物理ボディのaffectedByGravityプロパティをtrueにして重力加速度を受けるようにした場合と同じ動きになる。

以下の動画は、左側はaffectedByGravityプロパティをtrueにした場合、右側は線形重力ノードを使った場合の動画。まったく同じ速度で落ちる。

 

設定項目

線形重力ノードのアトリビュートインスペクタの設定項目を説明する。

Linear Gravityのアトリビュートインスペクタ

 

Name

ノードの名前。ソースコードから線形重力ノードにアクセスするときの識別子や、親ノードを指定するときに使用する。

 

Parent

親ノードを指定する。

 

Position

ノードの位置を指定する。先ほどの設定では、線形重力ノードがどの位置にあってもノードに与える力はすべて同じである。しかし、後述するFalloffを0以外にすると、線形重力ノードと鳥ノードの距離によって加速度が異なるようになる。

 

Strength

加速の強さを指定する。プラスの場合は垂直上方向、マイナスの場合は垂直下方向の加速度になる。残念なことにシーンエディタでは垂直方向かしか設定できない(Swift 2.2、XCode 7.3)。水平方向や斜めに力をかけたい場合はソースコードで設定する。

実際にやってみよう。先ほどシーンに配置した線形重力ノードは削除する。

TestScene.swiftのtouchesBeganメソッドを以下のコードに変更する。vector_float3の引数は、X軸、Y軸、Z軸のベクターを表している。Z軸は関係ないのでX軸とY軸を設定して斜めに加速するように設定した。

 

以下は実際のプレイ動画。鳥ノードが左上に向かって落ちていく。ちなみに、いつもの重力加速度にする場合はvector_float(0, -9.8, 0)にする。

 

Falloff

線形重力ノードの物理的効果の減衰率を指定する。公式リファレンスによると(鳥ノードとの距離 – minRadius)をマイナスfalloff乗した計算式で減衰率が決まると記載されている。
⇒公式リファレンス「SKFieldNode

When the force of a field node is calculated, the force is multiplied by pow(distance – minRadius, -falloff). The default falloff value is 0, which indicates that no attenuation takes place. Some types of field nodes ignore the falloff parameter entirely, while others change the default value to something that is more logical for that type of field node.

 

つまり、Falloffにプラス値を設定した場合は、線形重力ノードと鳥ノードとの距離が遠くなるほど加速度が弱くなるということだ。

実際にやってみよう。TestScene.swiftのtouchesBeganメソッドを以下のコードに変更する。線形重力ノードの位置を画面下端にし、垂直上方向の加速度を「2.0」、falloffプロパティを「3.0」に設定した。

 

以下の動画は、左側はfalloffが0、右側はfalloffが3.0の場合の動画。左側はすべての鳥ノードの加速度が同じになる。一方、右側は線形重力ノードから離れている鳥ほど加速が弱くなる。

 

Anim. Speed

乱気流やノイズのSKFieldNodeでのアニメーションの設定といった内容が、公式リファレンスに記載されているので本記事では検証しない。⇒公式リファレンス「SKFieldNode

 

Min. Radius

線形重力ノードとノードとの最小距離を指定する。設定値より短い距離にあるノードはすべて設定値と同じ距離として扱われる。

実際にやってみよう。TestScene.swiftのtouchesBeganメソッドを以下のコードに変更する。

減衰率を設定しない場合は、線形重力ノードと鳥ノードとの距離の長さに関わらず同じ加速度になるのでminimunRadiusプロパティを設定しても意味はない。

なので、検証ではfalloffプロパティに「3.0」、minimumRadiusプロパティに「400.0」を設定した。

 

以下は実際のプレイ動画。左側はminimumRadiusプロパティが「0」の動画、右側は「400.0」の動画。

線形重力ノードからの距離が400ポイントまでの茶鳥と赤鳥が同じ加速度になり、400ポイント以上の青鳥は左と右で同じになる。

 

Category Mask

ノードのカテゴリマスクを設定する。ノードのField Maskと線形重力ノードのCategory MaskのAND演算結果が0にならなければノードが加速するようになる。
⇒「ビットマスクとは

 

Enabled

チェックを入れると物理的効果が有効になる。一時的に無効にしておきたい場合はチェックを外す。

 

ノードごとに加速度と方向を変える

線形重力ノードを複数作成すれば、ノードごとの加速度や方向を変えることができる。

 

以下は実際のプレイ動画