PopcornFXエフェクトをUnityスクリプトで制御する話
どうも、エフェクトアーティストのぴょんさんです。
もうすぐ、SIGGRAPH Asia 2018が開催されますね。今年は東京で開催されるので、私も見に行く予定です。SIGGRAPHに参加すること自体が初めてなので、今からドキドキです。
さて、今回はPopcornFXで作成したエフェクトをUnityのスクリプトで制御する話になります。
環境
- Unity2017.4.0f1
- PopcornFX1.12
再生関係の制御
基本的にエフェクトは、PKFxFXというコンポーネントを通して扱うことになります。
- 生成する
「Play On Start」をtrueにしておけば、Instantiateメソッド等でオブジェクトを生成したときに、エフェクトを再生することができます。ただし、UnityのParticleSystemのStop Actionにあたるものがないので、生成する場合は終了後に破棄する処理も必要になります。
- 再生する
var fx = GetComponent<PKFxFX>(); fx.StartEffect();
こんな感じです。すでにエフェクトを再生していると、再度StartEffectを呼んでも、再生が終了するまで再生されないため、注意が必要です。
- 終了する
fx.TerminateEffect();
TerminateEffectを呼ぶことで、再生しているエフェクトを終了させることができます。
Attributeの制御
PopcornFXで設定したAttirbuteをUnityのScriptで制御するにはどうしたらいいか疑問に思っていたのですが、意外と簡単にできることがわかりました。
以下、実装例のコード。
こんな感じでできちゃいます。文字列で変更を加えたいAttribute名を指定します。PK Fx FXコンポーネントに設定するFXにAttributeが設定されていない場合、上記のコードはNullReferenceExceptionが起こるので注意が必要です。
あのパーティクルエディタを完全に理解した話
どうも、エンジニア系エフェクトアーティストのぴょんさんです。
昨今のリアルタイムエフェクト界隈では、UE4のNiagaraやUnityのVisualEffectGraphが盛り上がっているのではないかと思います。
そんな中、私は「PopcornFX」というパーティクルエディタを見つけ、触ってみました。意外と面白いものだったので、それについてちょこっとまとめたいと思います。
PopcornFXって何?
フランスのPersistantStudiosが出しているリアルタイム向けパーティクルエフェクトエディタです。(エディタやHP等の言語は英語なのでフランス語がわからなくても大丈夫です)
エディタ自体は無料で使用できますが、UnityやUE4で、作成したエフェクトを使用するには、有料のプラグインが必要になります。
一応UnityのAssetStoreではPopcornFXで作成されたエフェクトのサンプルが無料で公開されています。
どんなものが作れるの?
公式が公開している動画を見ると一目瞭然だと思います。
他のエフェクトエディタでも作れるようなエフェクトはもちろんですが、サウンドに合わせて動くエフェクトなんかも簡単に作れるみたいです。エディタからサンプルもダウンロードすることができます。サンプルはとにかく種類が豊富で、300以上はあると思います。
↑このようなモフモフ人間も作れるみたいです。
大きな特徴
コードを書きます。ちょこっと変わったことをしたいとか関係なく、コードを書くことがほぼ必要不可欠になります。そのため、アーティストには不向きかもしれません。(グラフィックスエンジニアとかTA向けなのかな???)
↑こちらもPopcornFXの大きな特徴の一つになるのではないかと思います。これで変数を作成すると、値をスライダーで調整できるようになります。そして、その変数をコードに加えてやれば、パーティクルのパラメータをスライダーで調整できることになります。この変数はエフェクトのパーツそれぞれに共通でもたせることができるので、エフェクト全体の色味や大きさ等を調整したいときなどに役に立ちます。
Unityに持って行った場合はそのパラメータをInspector上で調整できるようになります。(SDやSPに似てますね)
注意しておきたいこと
- プラグインが対応しているエディタのバージョンをよく確認しましょう
一番新しいのでいいでしょと思って作ったエフェクトを、Unityで再生することができず、作業が巻き戻る恐れがあります(実体験)
- ninjaに注意!
サンプルの種類が豊富で、どれもクオリティが高いので、サンプルを参考にエフェクトを作る場面が出てくると思います。すると唐突にコード上に「ninja」という単語が出てくるかもしれません。心の広さが試されます。
まとめ
PopcornFXについてちょこっとまとめました。使用してみた感じは、UnityのパーティクルシステムやUE4のパーティクルエディタよりかは使いやすいという印象でした。(あくまで私にとってですが)
もっと勉強して、ゲームをより盛り上げられるようなエフェクトを作成していこうと思います。
指定のコースにオブジェクトを移動させる『DOTween』
さんかくです。(/・ω・)/
今回は指定のコースを走らせるためにDOTweenを使用して実装しましたので紹介します。
これを使用するだけで簡単に自由な移動をさせることができます。
こんな感じに移動できます。
今回実装したオブジェクトの子オブジェクトとしてカメラを設定するとできます。
アセット
assetstore.unity.com
このアセットではオブジェクトの移動などのアニメーションを少ないコードで実装することなどができます。
またプロでは簡単な動作はコードを書かずにエディター上の設定のみで動かすこともできます。無料版でも十分に使えます。
環境
Unity2017.4.0f1
DOTween1.1.640
一部DOTweenProの機能を仕様しているので無料版で使える部分は自分で確認してください。
使い方
- 動かしたいオブジェクトを選択
- AddComponentでDOTweenPathを選択
- Ctrl+Shiftで動かしたい位置を選択
このようにScene上に白い点と白い線でルート表示されます。
Alt+Shiftで選択肢た点を消すことができます。
これで実行すると動きが確認できます。とても簡単です!
トロッコのように進んでいる方向に向いてほしいので、
『OrientationをToPath』にしています。
オブジェクトの角度を移動方向にしてくれるので、常に移動方向を向いています。
『PathTypeをCatmull Rom』にすることによって直線ではなく曲線に移動させることができます。
今回は一周させるために『Close Path』を選択し閉じています。
また、Editor上で移動する点を設置すると下の画像のように細かい数値でずれていたりします。
下のほうにあるwaypointsで設置した点の細かい数値を見たり、編集できるのでここで調整しましょう。
スクリプトで実行
同じことをスクリプトで実行することももちろんできます。
using UnityEngine; using DG.Tweening; public class TestPath : MonoBehaviour { void Start () { //行かせたい目的地 //必要ならば最初の位置もスクリプトでやるとEditorで設定しなくて済む Vector3[] path = new Vector3[3] { new Vector3(-10,0,0), new Vector3(0,0,10), new Vector3(10,0,0) }; transform.DOPath(path,2,PathType.CatmullRom) .SetOptions(true) .SetLookAt(0.01f,transform.forward); } }
DOTweenを使用するには宣言します。
using DG.Tweening;
DoPath(Vector3目的地の配列,時間,曲線か直線か)
SetOptions(Close Path設定し閉じるかどうか)
SetLookAt(lookAhead,オブジェクトの前方を設定し向かせる)
lookAheadがよくわからないのですが、0.01fで基本大丈夫そうです。
transform.DOPath(path,2,PathType.CatmullRom) .SetOptions(true) .SetLookAt(0.01f,transform.forward);
実行結果
同じ動きができています。
前回のgifと違うところは、前回はEditor上ですでにDOTweenPathを設定していたのでルートの線が見えてたと思いますが、今回は実行時スクリプトから生成されるので、最初にルートの線が見えてません。
終わりに
どうやっていろんなルートを走らせるのか、計算が大変そうだなと身構えてましたが、このアセットのおかげで簡単に実装できてしました。
デザイナーさんとかでも触りやすく思った移動ができると思うのでぜひ使ってみてください(*´▽`*)
オレオレシェーダによるマテリアルを使用してパーティクルエフェクトを作る話
どうも、ぴょんさんです。
今回は、自分で書いたシェーダのマテリアルをパーティクルのマテリアルとして使用した際に、「Shuriken」から色を変える方法がわからず半日ほど潰したため、その方法をメモとしてまとめます。
環境
- Unity2017.4.0f1(いつもの)
沼の始まり
上の図のパーティクルはどちらも以下のように「Color over Lifetime」を設定しています。
見てわかる通り、Beforeのほうは色も透明度も変わっていません。この時点で、シェーダのほうに何らかのことをしなければならないということがわかりました。
シェーダ側で時間経過で色が変わる処理を書くこともできますが、それをするとパーティクル全ての色が同時に変化してしまい、Afterの様にグラデーションを描くことはできません。
沼の終わり
いろいろと調べたり試行錯誤したりした結果、ようやく色を変更できるようになりました。
まずはソースから↓
StandardSurfaceShaderを作成し、少し改造したものになります。
重要なのは20行目です。
struct Input
{
float2 uv_MainTex;
float4 color : COLOR;
};
デフォルトだと、Inputはuv_MainTexしかありません。しかし、colorを付け足すことにより、「Shuriken」の色を変更するモジュールから値を受け取れるようになります。これにより、上図のAfterのように色を変えながら、徐々に透明になっていくエフェクトを作成できるようになりました。
参考
おわり( ゚Д゚)
[デザインパターン]ObjectPool
ひろたか('Д')です。先月は忙しく、久々の投稿となります。
さて今回は前回に引き続きデザインパターンの一つをご紹介いたします。
今回はご紹介するのは「ObjectPool」です。
目次
環境
今回はUnity2017.4.0f1を使用しています。
ObjectPoolとは
ObjectPoolは複数のオブジェクトの生成と破棄によるコストを押さえるために使用されます。
オブジェクトが必要になるときに新しく生成し、不要になったら破棄するのではなく、実行時にある程度生成しておき、不要になったらオブジェクトを破棄せずに再利用することで、生成や破棄によるコストを押さえることが出来ます。
使用例としてはシューティングゲームの弾のように大量に使い、寿命の短いモノによく使われます。
例
弾プレハブを生成するクラスとそこから未使用の弾を取得し、弾を撃つスクリプト2つのサンプルです。
gistc059e1c69a30102941bcf0000cd22527
Bulletは必要・不要になった際にActiveを変更しています。こうすることで生成・破棄のコストを削減できます。
最後に
今回の実装ではBulletのみにしか対応していませんが、基底クラスから派生させるなどすれば様々なオブジェクトに対応させることが出来ます。皆さんも是非使ってみてください。
参考サイト
【UE4】手軽にいい感じの炎を作成する話
どうも、ぴょんさんです。
涼しくてときどき肌寒い季節になってきました。体調をくずさないように、自分にホワイトでいきたいと思います。
さて、さてさて
今回はエフェクトの話です。
先日行われたCEDECで聞いた話の中に、炎エフェクトの実装例の1つとして紹介されたものがあったので、それを参考に炎を作成してみました。
環境
- UnrealEngine 4.18
こんな感じで作った
以下は炎のマテリアルになります。これをパーティクルのマテリアルとして扱い、炎を作成しました。
テクスチャは以下の2つを使用しています。
まずは、炎の形の作り方について詳しくまとめます。
①で雲模様のテクスチャをゆがませつつ、y軸(V)でスクロールさせたものを作成しています。
②で使用している、LinearGradientというノードは↓のような上から下へとだんだん白くなっていくグラデーションを作成してくれます。今回使用しているのはVGradientですが、UGradientは横のグラデーションになります。
このグラデーションと、楕円を半分で切ったテクスチャを組み合わせて、炎の大まかな形を作成しています。
最後に①と②を掛けて、黒~白をα値の0~1として扱うことで、炎の形は完成です。
仕上げに色を足したり掛けたりすることで、炎エフェクトの出来上がりです。(ね、簡単でしょ)
まとめ
こんな感じで、炎エフェクトを作成することができました。これに火の粉や煙を加えれば、いろんなところで使えるのではないかと思います。また、今回の方法を応用して、炎以外のエフェクトなんかも色々作れるのではないかと思います。(実際、Unityでいろいろ作ってマス)
参考
おわり(^<^)
Unityコルーチンについて
さんかくです。(/・ω・)/
今日はUnityコルーチンについて紹介したいと思います。
コルーチンとは
コルーチン(英: co-routine)とはプログラミングの構造の一種。 サブルーチンがエントリーからリターンまでを一つの処理単位とするのに対し、コルーチンはいったん処理を中断した後、続きから処理を再開できる。
(Wikipediaからの引用)
ということなのですが、Unityでのコルーチンとは
「いったん処理を中断した後、続きから処理を再開できる」
と考えて良いと思います。
何秒後に再び実行させるなどの処理をさせることができます。
どのような場合に使うか
- 321のカウントダウンを毎回Updateで計算させずに実行したい。
- 周囲に敵がいないか探索する場合、10毎秒に探索させることにより余計な呼び出しを減らす。
- Update関数に入れずにコルーチンを使用することによって、Update関数をきれいにすることができる。
カウントダウンの表示をコルーチンで実装
まずはコルーチンを使わない場合です。
using UnityEngine; using UnityEngine.UI; public class Countdown : MonoBehaviour { [SerializeField] Text t = null; float totalTime = 0.0f; private void Start() { t.text = "3"; } void Update() { totalTime += Time.deltaTime; if (totalTime >= 3) t.gameObject.SetActive(false); else if (totalTime >= 2) t.text = "1"; else if (totalTime >= 1) t.text = "2"; } }
次にコルーチンを使った場合↓
using UnityEngine; using UnityEngine.UI; using System.Collections; public class Countdown : MonoBehaviour { [SerializeField] Text t = null; private void Start() { StartCoroutine(UpdateCountdown()); //メソッド名でもOK //StartCoroutine("UpdateCountdown"); } IEnumerator UpdateCountdown() { t.text = "3"; yield return new WaitForSeconds(1); t.text = "2"; yield return new WaitForSeconds(1); t.text = "1"; yield return new WaitForSeconds(1); t.gameObject.SetActive(false); } }
Update関数を無くすことができたり、秒数を持つ機能のおかげで毎回合計時間を取得していたtotalTime変数、他にも毎回時間が指定時間経過したかの計算を無くすことができました。
コルーチンを使うことにより、綺麗にわかりやすくコードを記述することができます。
コード解説
using System.Collections;
コルーチンを使用する際に必要です。
IEnumerator UpdateCountdown() { ...省略 }
コルーチンにはIEnumerator を返す関数を作ります。
IEnumerableでは無いです。よく間違えます(・ω・)
Debug.Log("1"); yield return new WaitForSeconds (1); //1秒後に再開 Debug.Log("2"); yield return null;//次のフレームで再開 Debug.Log("3"); yield break;//コルーチンを途中で終了 Debug.Log("4"); // yield return StartCoroutine(コルーチン名);//コルーチンの中で別のコルーチンを実行することもできます
基本的にコメントに書いてある通りのことができます。
今回はyield return new WaitForSeconds (1);を使っていたので、
文字を変更→一秒待機→文字を変更・・・
をわかりやすく記述することができました。
ちなみに上の例の結果は下のようになります。
1 2 3
yield break;で途中で終了したのでDebug.Log("4");は実行されません。
StartCoroutine(UpdateCountdown()); StartCoroutine(”UpdateCountdown”); StartCoroutine("コルーチン名",引数1);//引数は一つまで StartCoroutine(コルーチン名(引数1,引数2));
コルーチンの実行にはStartCoroutineを使用します。
コルーチン名をstringで入れることもできます。
stringの場合は引数を一つしか持たせることができません。
終わりに
コルーチンは便利ですが、しっかり管理しないと思わぬバグなどを起こしたりもするので気をつけてください。
参考サイト
docs.unity3d.com
使用するときお世話になりました。↓
developer.wonderpla.net