【SpriteKit】爆発や雪などの表現ができる「Particle File」について

初めまして。アプリ道場の11日目、Koi-fumiです。
普段は、水彩やアクリルによる絵画を描いてます。

仕事から趣味まで、周りに絵を描く人が多いので、自分やみんなの作品、また展示・イベントの活動などをアプリの形にも出来たら楽しそうだなと思い、今のところ主にSwiftでSpriteKitに取り組んでいます。

その中で、簡単なタップゲームをつくっている間に、綺麗なエフェクトが作れるSpriteKitのパーティクルにうっかりハマって遊んでしまったので、今回はその「SpriteKit Particle File」を取り上げてみる事にしました。

#パーティクル「SpriteKit Particle File」の追加の仕方
Xcodeの左側、プロジェクトナビゲーターのGameViewController.swiftやGameScene.swiftやらのファイルが並んでいる所で右クリックして、「New File...」から「iOS」＞「Resource」＞「SpriteKit Particle File」を選択します。



<img width="896" alt="day11_01.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/ee191d8b-8b12-1191-df85-cd05364a57d7.jpeg">


「Particle template」で、作りたいイメージに近そうなパーティクルを選択します。（全８種類あり。詳細な内容は後述）


<img width="896" alt="day11_02.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/7f6af68c-2d76-a49d-f1a5-f1ef398cbdaa.jpeg">


わかりやすい名前をつけて、Createで作成します。


左側のナビゲーターエリアに、先ほど作った「〜〜〜.sks」というファイルが追加されます。
このファイルを選択すると、動いてるプレビューと、パーティクルについて各種の設定項目がならんだインスペクタが右側に表示されます。


<img width="896" alt="day11_03.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/9c209084-2056-d63c-fe66-0e3fd329c1a9.jpeg">



もしプレビューに何も表示されない場合は、プレビュー画面のどこかをクリックしてみて下さい。
クリックされた所に表示されます。
（Bokeh、Fireflies、Smoke、Snowは最初は何も表示がない状態になってて、クリックでプレビュー表示されると思います。）
何度クリックしても出てこない場合は、そのプロジェクトを１度閉じて開き直してみてください。


右側のインスペクタのさまざまな設定項目の数値を変更すると、リアルタイムでプレビューも変化します。


<img width="896" alt="day11_04.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/d700fc66-0554-9912-7695-de4ac4fafefb.jpeg">



プレビュー画面のパーティクルは、ドラッグで動かす事が出来るので、炎や煙のパーティクルなど、動きに合わせて揺らぐのが確認できます。


<img width="896" alt="day11_05.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/8fe6388a-f7b3-2924-1494-20a366ed6e25.jpeg">



#Particle templateの種類と内容について（動画あり）
Particle template（全８種）には、どんな内容のものがあるのか？
動画の資料を作っておいたら便利かなと思い、Xcodeでのプレビュー画面を撮ってみました。

８種類のファイルを作って、テンプレートの並び順に撮り流してるだけの簡単なものですが、資料用にどうぞ。
https://youtu.be/gdzapAhd3-o
（YouTubeに飛びます。画面左上にプレビューに表示しているテンプレート名を入れています）


<img width="830" alt="day11_06.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/a2625df1-d606-69de-a878-a9f3ba85d202.jpeg">


**Bokeh**
ボケ。写真用語のボケ（英語でも日本語でも一緒のよう）レンズの焦点範囲外のぼやけた部分を表しますが、エフェクトの内容を見るに、特に照明や明かりがボケた効果を表している様です。
ちょっと重いです。

**Fire**
火。設定をかえると広範囲に広がって舞い上がる炎のような感じにもなります。
使い所がたくさんありそう、使い勝手が良さそうなテンプレートの１つです。

**Fireflies**
蛍。黄色い丸い光が舞う幻想的な雰囲気のパーティクルです。

**Magic**
魔法。FrieFliesをファンタジックにした感じのような色のパーティクルです。

**Rain**
雨。名前の通りに雨が降る感じのパーティクルです。
「Particle Texture」の画像を、星の画像に変えたりしてキラキラ降らせたりなどしてみると楽しいかもしれません。

**Smoke**
煙。黒い煙がもくもくと立ち上るようなパーティクルです。
「Color Ramp」の色を変えたり、「Blend Mode」を少し変更するだけで白い煙や光るオーラみたいな雰囲気のものや、妖しい感じのもくもくしたものが手軽に作れます。

**Snow**
雪。今の時期にピッタリな、白い雪が舞い降るようなパーティクルです。
こちらもRainのように「Particle Texture」の画像を、星やハートやに変えたりするだけで可愛い雰囲気の演出が作れると思います。

**Spark**
火花。勢い良く飛び散る火花のパーティクルです。
使い所がたくさんありそう、使い勝手が良さそうなテンプレートの１つです。
　
#パーティクルの設定項目「SpriteKit Particle Emitter」について
前述のテンプレートのパーティクルの、（画面右側に表示されている）「SpriteKit Particle Emitter」の各項目の数値やParticle Textureの画像を変更する事で、様々な雰囲気のパーティクルを、プレビューで見ながら作成する事が出来ます。


<img width="900" alt="day11_07.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/93408865-5bd5-9549-b5e5-d17546e5f0bb.jpeg">


「＋」「−」の表示があり数値が設定できる部分は、
・数字の部分をダブルクリックして直接数値を入力する
・左右の「＋」「−」部分をクリックして数値を少しずつ増減させる
・変更したい箇所の数値の上にカーソルを持って行き、左右のドラッグで増減させる
のどれかの方法で数値を変更できます。
カーソルが「左右に矢印のついた形」の表示になっているとき、左にドラッグで「マイナス」に、右にドラッグで「プラス」に数値を増やせます。


（Particlesの「Birthrate」をドラッグで急激に数を増やすと、処理が重くなって大変な事になります。。。Xcode固まりました。。。ここは、ほどほどに）


設定項目は次のようなものがあります。

##Background
プレビュー画面の背景色を変更します。

##Particle Texture
パーティクルの粒子として使用する画像を設定します。

プロジェクトに入れてある画像から選択できます。
あまり複雑な画像を入れると、他の設定との絡みでかなり処理が重くなるようなので、注意です。

SpriteKitテンプレートに入っている宇宙船の画像を面白半分で選択すると、他の部分の設定次第ではえらい目に合う（重すぎてなかなか操作できなくなる！）場合もあります。

##Particles
**Birthrate**で、粒子の発生数を設定します。
0では何も発生しません。マイナスの値にはなりません。

あまり大きな数値を設定すると処理が重くなって、大変な事になります。。。

**Maximum**に0より大きい数値をいれると、その数値で発生する粒子の数に制限がかかります。
Birthrateを100にしていても、Maximumを10にすると、10個の粒子しか存在できなくなるので、10個でた時点でその10個の寿命が尽きるまで、次の粒子が発生しなくなります。


##Lifetime
発生させた粒子の寿命を設定します。

0以下にはなりません。
0にしても、「Birthrate」が0でなければ、一瞬で粒子が発生〜消滅の繰り返しで、発生箇所の部分でパラパラっとチラつくようなパーティクルが出来ます。

##Position Range
粒子の発生範囲を設定します。

**X**の値を、マイナスでもプラスでも数値を大きくすればするほど、パーティクルは横に広がっていきます。
**Y**の値を、マイナスでもプラスでも数値を大きくすればするほど、パーティクルは縦に広がっていきます。

XとYの両方の数値を大きくすると、画面全体を粒子が飛び舞うような、テンプレートのFirefliesやMagicのような感じになります。

<img width="1636" alt="day11_08.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/446521dc-9bcd-7397-63ca-4e03d1a19d40.jpeg">


##（Position）Angle
粒子の飛んでいく方向を角度で指定します。
0〜360までで小数点３位まで設定できます。

**Start**で方向を指定します。
0は右方向、90で真上に、180で左方向に、270で真下に、360で１周回って再び右方向になります。
まっすぐ右、３時の方向を開始として、数値が大きくなるにつれて反時計回りに角度が変わります。

<img width="1084" alt="day11_09.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/dae4bb09-ea10-8016-d9dd-96449b42821a.jpeg">


**Range**は方向にランダムの範囲を与えます。
数値が大きくなるほど、粒子の飛んでいく方向の範囲が広くなっていきます。
360で、発生範囲（Position Range）を中心に全方向へ飛んでいきます。

##（Position）Speed
粒子の放出される速度を設定します。

**Start**の数値が大きいほど粒子が早く移動していきます。

**Range**に0以外の数値を設定すると、各粒子の速度に設定範囲内でランダム性を与えます。
粒子ごとにスピードの違いが出てきます。

##（Position）Acceleration
言葉としては加速度、加速率です。ここに数値を設定すると、粒子が発生してからその後に流れていく向きを作れます。

**X**はX軸方向（横）への流れで、マイナスの数値で左側へ、プラスの数値で右側へむかって徐々に流れていきます。
**Y**はY軸方向（縦）への流れで、マイナスの数値で下の方へ、プラスの数値で上の方へむかっていきます。

どちらも0だと、「Angle」の項目で設定していた方向にしか流れませんが、こちらも設定してあげることで、少し複雑な流れを作ることができます。

例えば、「Angle」でStartを90°にして、真上に放出される設定にした上で、こちらのAccelerationのYにマイナスの数値を設定すると、噴水のように上にむかって放出されてから下に流れて落ちていくようなパーティクルが出来ます。

Xに値を設定すれば、風に流れる煙みたいな表現ができます。

数値の値が大きいほど、指定した方向へむかっていく力が強くなります。


##Alpha
透明度を設定します。

**Start**は、発生時の透明度の設定です。
0だと完全な透明になってしまいますので、結果として粒子が発生しててもまったく見えなくなります。

**Range**で透明度のランダム範囲を設定できます。
Startが0でも、こちらに0より大きい数値を設定すれば、ランダムな透明度の粒子が発生するので見えるものも出てきます。

**Speed**で時間の経過とともに透明度を変化させる事ができます。
StartとRangeはマイナスの値は設定できませんでしたが、こちらはマイナスにも振れます。

マイナスの値だと徐々に透明になっていきます。
プラスだと徐々に不透明になっていくので、Startを0にしてこちらをプラスに振ると、徐々に粒子が浮かび上がってくるようなものが作れます。


##Scale
粒子サイズを設定します。
Particle Textureの画像をどのくらいの大きさや、ランダム性を持たせて表示させていくかを変更できます。

**Start**は発生時の粒子の大きさです。
1が画像の原寸として、何倍の大きさにするか？なので、用意した画像より小さくしたい時は、0.8とか0.以下小数点３位までで細かく調整できます。

**Range**に0以外の数値を入れる事で、発生する粒子のサイズにランダム性を持たせる事ができます。
こちらもStartと同じく何倍の大きさにするかなので、マイナスは設定できません。

**Speed**で時間の経過とともにサイズを変化させる事ができます。
こちらはマイナスの数値で徐々に小さく、プラスの数値で徐々に大きくなっていきます。

星やハートなどハッキリした形の画像を飛ばすときには、極端に拡大するとボヤけた感じになってしまいます。

##Rotation
粒子の角度を設定します。
３つのどの項目も０〜360までで小数点３位まで設定できます。

わかりやすいようにテンプレートSnowのParticle Textureを「星」の画像にして、数値をいじってみた画像を作りました。
（※「星」の画像は、角度が分かりやすいように、上を向いた頭の部分を赤く染めてあります）

**Start**は、パーティクル発生時の粒子の角度です。
0のときはそのまま「☆」の形のパーティクルが降ってきますが、数値を入れるとその分傾いた☆になります。

<img width="1476" alt="day11_10.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/fdd88bef-bdb4-5406-c060-43f6fe11be4c.jpeg">


**Range**で角度の振れ幅を設定できます。
ここに0より大きい数値を入れると、その範囲でランダムに傾いた星のパーティクルが降ってきます。
Startが「0」でもRangeに0以外の数値を設定すれば、発生する星の角度は変わります。

<img width="900" alt="day11_11.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/989e66b5-9d9d-dc42-fc26-30684b38b4b3.jpeg">


**Speed**に数値をいれると、☆が回転しながら降ってきました。
数値が大きいほど早く回転します。

（添付のGIFアニメは、Speedを90にしたものです。容量削減したので、カクカクしてますが、実際は滑らかに回転しています）

![day11_12_s.gif](https://qiita-image-store.s3.amazonaws.com/0/102335/d200335f-6c13-de9e-0040-a822db5e8763.gif)


##Color Blend
粒子の固有色と下記のColor Rampとの色の合成（混合）についての設定です。

**Factor**で、粒子のParticle Textureの画像の色に、どれだけ下記のColor Rampで設定した色を乗せるか？の具合を設定します。
0にするとColor Rampの色設定がまったく反映されなくなり、Particle Textureの画像の色になります。

**Range**に0以外の数値を設定すると、Color Rampの適応具合（Factorの設定）にランダム性を持たせることができます。
Particle Textureの固有色の粒子とColor Rampの色の粒子が混じって出てくるようになります。

**Speed**に0以外の数値を設定すると、時間経過によるColor Rampの適応具合（Factorの変化）を指定できます。
プラスに振ると、Particle Textureの固有色からColor Rampの設定色に染まっていきます。（Color Rampの設定色がどんどん出てくる）
マイナスに振ると、Color Rampの設定色からParticle Textureの固有色になっていきます。（Color Rampの設定色がどんどん抜けていく）


##Color Ramp
粒子の色（発生してから消滅するまでの色）を設定します。

色のバーの部分をクリックすることで、複数の色を追加して行くことができます。
（作りすぎた色を削除したい場合は、消したい色の丸印の部分を下へドラッグで削除できます。）

<img width="900" alt="day11_13.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/e1ed79b8-9715-0517-c965-24e073ea1da6.jpeg">


２色以上でグラデーションを作った場合、パーティクルの発生から消滅にかけて左の色から右の色へと変化していきます。



##Blend Mode
粒子の描画モードを変更します。全７種類あります。
（Photoshopのレイヤーの描画モードで言うところの、加算やスクリーンや乗算などです）

粒子の色と、その背後にくるものの色（背景など）をどのような関係で描画するかを７種類のモードから選択できます。

**Alpha、Add、Subtract、Multiply、MultiplyX2、Screen、Replace**

背景を透過させた星の画像を用意して、グレーの背景にそれぞれのモードにした比較画像を作りました。


<img width="706" alt="day11_14.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/102335/b820ffaf-5601-ba5f-9bdf-16511740b262.jpeg">

光ってる感じの、明るくしたいものには、AddやScreenが向いてます。（白っぽい背景色にはあまり目立たなくなるかと思います）
特にAddは粒子同士が重なった部分が明るくなっていくので、光輝くような火花っぽいものに向いてます。


***

これらのSpriteKit Particle Emitterの各項目を変更するだけで、いろいろな効果が作れます。
うっかり横道にそれて、いろいろと数値をいじって遊んでしまうのも納得です！


基本的にSpriteKit Particle Fileでは、設定したパーティクルをずっと垂れ流してるだけですが、「Particle Texture」の画像や、「Color Ramp」の色の変化に、「Position Range」の各種項目や「Scale」に「Rotation」などを中心に、SpriteKit Particle Emitterの設定を工夫して、コード上でもいろいろと調整したり、他のspriteNodeとの動きを絡めたりすると、かなりいろいろな表現が出来るのでは？と思いました。