Character Particleを使うためにPlayｍakerのカスタムアクションを作ってみた。

#はじめに。
[Character Particle](https://www.assetstore.unity3d.com/#!/content/95555?aid=1101l3dwM) はパーティクルに文字列を指定することが出来るUnityのアセットです。

Unity標準のパーティクルシステム（Shuriken）と合わせて使うので、慣れている人は凄く簡単に、そうでない人もサンプルをコピペすることでそれなりに簡単に文字列をパーティクルに出来ます。

アセットについての詳しい紹介は[開発者であるオノッチさんのブログ記事](http://onoty3d.hatenablog.com/entry/2017/08/11/031355)を見て頂くとして、歌うキャラクターの歌詞を表示したり、魔法陣から文字が浮かび上がらせたり、おどろおどろしいフォントを使ってホラーの雰囲気を表現するなど様々な使い道が思いつきます。

私は擬音にチャレンジしていますが、そこで作った再生用の[Playmaker](https://www.assetstore.unity3d.com/#!/content/368?aid=1101l3dwM)用のカスタムアクションを使用例と共に紹介したいと思います。

##ソフトウエアのバージョン
記事を書く際に使用したソフトウエアのバージョンは以下になります。

- Unity 5.6f1
- [Character Particle 1.2](https://www.assetstore.unity3d.com/#!/content/95555?aid=1101l3dwM) 
- [Playmaker 1.8.5](https://www.assetstore.unity3d.com/#!/content/368?aid=1101l3dwM)

#準備(パーティクルの用意）
今回のカスタムアクションはParticle Systemを再生と停止するだけですので使用するParticle Systemを用意する必要があります。
予めUnity標準のshirikenにてパーティクルの行い、Scene上に配置しておいて下さい。
設定のフローについては [bibinbaさんのブログ記事](http://bibinbaleo.hatenablog.com/entry/2017/08/01/103639) が参考となります。

なお以下の項目は[Playmaker](https://www.assetstore.unity3d.com/#!/content/368?aid=1101l3dwM)上で設定しますが、カスタムアクションが呼ばれる前はInspectorの値が反映されます。

- Loop
- StartSize
- Charcter ParticleコンポーネントのText

また以下の項目はスクリプトで設定されます。

- Duration
- MaxParticles
- Emisson内のRateOverTime

ちなみに私の環境では以下のようになっています。
![ps_1.PNG](https://qiita-image-store.s3.amazonaws.com/0/30693/c1377b8b-0ebb-53d6-8458-d0827a5ae30b.png)

MainとEmissionで上記項目以外で大事そうなのはStartLifetime（パーティクルの生存時間）でしょうか。
パーティクルを飛ばしたい距離などに応じてVelocity over Lifetimeあたりと調整して頂ければいいと思います。


#カステムアクション
[Playmaker](https://www.assetstore.unity3d.com/#!/content/368?aid=1101l3dwM)にて使用するカスタムアクションをAssetsフォルダに配置します。

```C#:CharcterParticlePlayFsm.cs
using UnityEngine;
using Onoty3D.CharacterParticleAsset.Scripts;

namespace HutongGames.PlayMaker.Actions
{
	[ActionCategory("CharacterParticle")]
	[Tooltip("キャラクターパーティクルを再生する")]
	public class CharcterParticlePlayFsm : FsmStateAction
	{
		[Tooltip("再生するCharacterParticleをAddComponentしたオブジェクトを指定する")]
		public ParticleSystem particle;

		[Tooltip("パーティクルとして表示するテキストを設定する")]
		public FsmString Text;

		[Tooltip("再生時のパーティクルのサイズを設定する")]
		public FsmFloat StartSize;

		[Tooltip("指定した文字列を再生する時間")]
		public float playTime = 1f;

		[Tooltip("ループするか")]
		public bool loop = false;

		[Tooltip("ループするときに間をあけない")]
		public bool noWaitLoop = false;

		public override void OnEnter()
		{
			PlayOnceSetting(Text.Value.Length, StartSize.Value);
			CharParticlePlay(Text.Value);
			Finish();
		}

		public void PlayOnceSetting(int textLength, float startSize)
		{
			var main = particle.main;

			// パーティクルの動作時間
			main.duration = playTime;
			// ループ
			main.loop = loop;
			// 放出するパーティクルの最大数
			main.maxParticles = (loop && noWaitLoop) ? (textLength * 100) : textLength;
			// 放出される際のパーティクルの初期サイズ
			main.startSize = startSize;

			// テキストの長さと放出時間を調整
			var em = particle.emission;
			em.rateOverTime = (textLength + 1) / playTime;
		}

		private void CharParticlePlay(string text)
		{
			// 放出するテキストを設定する
			CharacterParticle charParticle = particle.GetComponent<CharacterParticle>();
			charParticle.Text = text;

			// パーティクルを再生
			particle.Play();
		}
	}
}
```

あと再生中のパーティクルを停止させるカスタムアクションも用意しておきます。

```C#:ParticleStop.cs
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
	[ActionCategory("CharacterParticle")]
	[Tooltip("パーティクルを停止する")]
	public class ParticleStop : FsmStateAction
	{
		[Tooltip("停止するParticleをAddComponentしたオブジェクトを指定する")]
		public ParticleSystem particle;

		public override void OnEnter()
		{
			particle.Stop();
			Finish();
		}
	}
}
```

[Character Particle](https://www.assetstore.unity3d.com/#!/content/95555?aid=1101l3dwM)用のカスタムアクションでは無いですが [Playmaker](https://www.assetstore.unity3d.com/#!/content/368?aid=1101l3dwM) 上でループ再生を止めるのに使用します。

#Playmakerでの使用方法
[Playmaker](https://www.assetstore.unity3d.com/#!/content/368?aid=1101l3dwM)のステータスに追加する方法は、他のアクションと変わらずアクションブラウザから行います。
カテゴリは「CharacterParticle」を設定してあるのでそこから「CharcterParticlePlayFsm」を選択してください。

![ccfms.PNG](https://qiita-image-store.s3.amazonaws.com/0/30693/1f777afb-c505-c601-2b5b-a093c7674b6b.png)

アクションはパーティクル再生を開始した時点で FINISHED が呼ばれます。（一回再生でもループする場合でも）
必要に応じて遷移を追加して次のアクションへと繋げて下さい。

##設定項目
- Particle：再生するパーティクルを指定（Charcter ParticleがAddComponentしてあること）
- Text：パーティクルに使用するテキスト
- Start Size：再生時のパーティクルの初期サイズ
- Play Time：Textを１回再生する時間を指定
- Loop：パーティクルを連続再生するか
- No Wait Loop：連続再生する場合に隙間を入れない様にするか

StartSizeは同じパーティクルで異なる文字列を放出する場合に大きさの調整をしたいと思いプロパティ化しました。
同様にPlayMaker上から調整したい値があったら追加するとよいでしょう。

##一回再生の設定例
「じいいいいいいい」という文字列を２秒で再生します。

![jii.PNG](https://qiita-image-store.s3.amazonaws.com/0/30693/b83b4494-8ec6-c0f1-f87a-88ddedd8e9f7.png)

![oneshotl1.gif](https://qiita-image-store.s3.amazonaws.com/0/30693/577adc47-403c-74a5-89d9-52c94cace103.gif)

##ループ再生の設定例

「ぺた」という文字列をループ再生します。

![peta2.PNG](https://qiita-image-store.s3.amazonaws.com/0/30693/661a69e4-7b1d-0f60-a919-ce0cfd9de37b.png)

![loopSide1.gif](https://qiita-image-store.s3.amazonaws.com/0/30693/c2c1c6ac-2739-7b60-e190-0301d0ff2fad.gif)

##ループ再生の停止
Loopにチェックを入れてループ再生を行った場合、自動で停止しません。
必要なタイミングでパーティクルを止めるカスタムアクションを呼び出して、パーティクルを停止させてください。

パーティクル再生のカスタムアクションと同じくカスタムアクションが呼ばれた時点で FINISHED が呼ばれます。
必要に応じて遷移を追加して次のアクションへと繋げて下さい。

![sop.PNG](https://qiita-image-store.s3.amazonaws.com/0/30693/88901226-db79-4621-ab35-a345c4031194.png)

停止のカスタムアクションは Particle の項目に停止するパーティクルを設定する必要があります。
再生のカスタムアクションに設定したパーティクルと同じもの設定してください。

#おわりに。
[Character Particle](https://www.assetstore.unity3d.com/#!/content/95555?aid=1101l3dwM) はUnity標準のパーティクルに新たな魅力を加えて多彩な表現を引き出すことが出来るとても素敵なアセットです。
ここで紹介した使い方はほんの一例ですので今回のスクリプトが期待通りに動かないケースもあるでしょうが、簡単なスクリプトなので用途に合わせてカスタマイズしてもらえれば。

この楽しいアセットがより多くの方に使われるといいなと思います。