今回はBlender、UnityのVisualEffectGraph、ShaderGraphを使って剣の軌跡のエフェクトを作成していきます。
以前スクリプトからメッシュを作成し剣の軌跡エフェクトを作成しました。
今回はBlenderで軌跡用のメッシュを作成し、それをUnityに取り込んでVisualEffectGraphを使って剣の軌跡を作り、ShaderGraphを使って見た目を調整をするという方法で作ってみます。
以下のような感じの剣の軌跡エフェクトが出来ました。
今回の記事は以下のYouTubeの動画を参考にさせて頂きました。
Blenderで軌跡用のメッシュを作成する
まずは軌跡用のメッシュをBlenderで作成していきます。
UnityのProBuilderでも作れますがデフォルトのUVMapの設定がBlenderで作った方が便利なので今回はProBuilderは使いません。
今回使用しているBlenderのバージョンは3.2です。
Blenderを開いたら元からあるCubeオブジェクトを選択し、Xキーを押して出てきたウインドウで削除を選択します。
Shift+Aキーを押してトーラスオブジェクトを作成します。
Tabキーを押して編集モードに移動し、面選択モードに変更し、トーラスの中心の内側のメッシュを選択する為に内側のひとつのメッシュをAltキーを押しながらマウスの左ボタン(Blenderの古いバージョンの場合は右ボタン)を押して横つながりのメッシュを選択します。
縦の繋がりが選択されてしまった場合は横の辺あたりの面を選択すると横つながりの面を選択出来ます。
Shiftキーを押しながらAlt+面の選択をすることで複数のリング状の面を選択出来ます。
選択したらXキーを押して頂点を選択して削除します。
このままの形状でもいいんですが、剣の軌跡なのでもうすこし平らな形状にします。
Aキーを押して全てのメッシュを選択し、Sキー(サイズ変更)を押した後Zキー(Z軸に固定)を押しマウスをドラッグして平らな形状になったらマウスの左ボタンを押します。
これで剣の軌跡用メッシュが出来ました。
トーラスを作成した時のデフォルトの設定でUVMapが自動で作成されているので自分でUVMapの作成はしません。
これを出力します。
BlenderメニューのFile→エクスポート→FBXを選択します。
わかりやすいようにデスクトップにSwordSlashという名前で出力します。
オブジェクトタイプでメッシュのみを選択し、トランスフォームでトランスフォームを適用にチェックを入れます。
トランスフォームに適用にチェックを入れる事でオブジェクトの空間の変換をオブジェクトにベイクし、Blenderと他のソフトでの座標軸の違いがあった時でも変換が行われないようにします。
UnityのAssetsフォルダにデスクトップに出力したSwordSlash.fbxファイルをドラッグ&ドロップしてインポートします。
剣の軌跡用のメッシュを用意しました。(._.)
zipで圧縮しているので解凍してご自由にお使いください。
キャラクターの設定
剣の軌跡エフェクトを作成するということで、確認する為の剣を振るキャラクターが必要になってきます。
キャラクターに剣を持たせ移動と攻撃キーを押したら剣を振るようにしておいてください。
わたくしが使用したキャラクターはスタンダードアセットのEthan(キャラクターは何でもよい)で、剣は自分で作った物(剣もアセットストアでインストールしたものやCubeの形状を変更しただけでもよい)、剣を振るアニメーションはアセットストアで「Warrior Pack Bundle 2 FREE」で検索して出てくるもの(剣を振るアニメーションであればなんでもよい)を使用しています。
剣を振るキャラクターなんて作れない!
という方は
の記事の順番に読んで頂くと剣を振るキャラクターの作成まで出来ますので参照してみてください。
キャラクターのスクリプトに関しては後でエフェクトの操作部分もあるので作ります。
剣の軌跡エフェクトの作成
UnityにBlenderで作成した剣の軌跡のメッシュを取り込みました。
あとはこの剣にマテリアルを設定し、スクリプトで動かして使う事も出来ますが、今回はUnityのVisualEffectGraphを使って剣の軌跡エフェクトを作成していきます。
Assetsフォルダで右クリックからCreate→Visual Effects→Visual Effect Graphを選択し、名前をSwordSlashとします。
SwordSlashをヒエラルキーのキャラクターにドラッグ&ドロップして配置します。
キャラクターの子に配置したことでこのエフェクトはキャラクターが移動や回転をするとそれに合わせて相対的に移動と回転をすることになります。
SwordSlashゲームオブジェクトのTransformのPositionとRotationは現時点で全て0、Scaleは全て1になっているのを確認してください。
Visual Effect Graphを使ってエフェクトの作成
SwordSlashをダブルクリックして開きます。
SpawnコンテキストのConstant Spawn Rateブロックを選択し、Deleteキーを押して削除します。
さらにSpawnコンテキストを選択し、Spaceキーを押した後Singleと入力し、出てきたSingle Burstブロックを選択し、Countに1を入力して、最初に1つのパーティクルを発生させます。
InitializeコンテキストのCapacityを1にし、同時に1つのパーティクルだけ存在するようにします。
Set Velocity RandomブロックとSet Lifetime Randomブロックは選択し、Deleteキーを押して削除します。
Initializeコンテキストを選択し、Spaceキーを押して検索窓にSet Lifetimeと入力して追加し、Lifetimeを0.12とします。
つまりパーティクルが発生してから0.12秒後にはパーティクルが消失します。
ここで入力する数値は後で調整が必要になります。
次にSet Lifetimeブロックを選択した状態でSpaceキーを押し、検索窓にSet Sizeと入力し選択して追加したらSizeを1.1にします。
表示するパーティクルは剣の軌跡のメッシュの形状で表示したいので、Output Particle Quadコンテキストを選択し、Deleteキーを押して全てのブロックを含めて削除します。
さらにUpdate ParticleコンテキストのParticleポート部分を下にドラッグし、出てきたウインドウでOutput Particle Meshコンテキストを選択します。
Output Particle MeshコンテキストのMeshに先ほどBlenderで作成し、Unityに取り込んだ剣の軌跡用のメッシュを設定します。
先ほどInitialize Particleに追加したSet Lifetimeブロックの右のチェックボックスのチェックを外し、一旦パーティクルの生存期間を設定しないようにします。
チェックを外したのは変化を加えた時に即座に確認出来るようにする為で、エフェクトが完成したら再度チェックを入れる必要があります。
シーンビューを確認すると以下のようにキャラクターの地面を取り囲むようなエフェクトが表示されるはずです。
Output Particle MeshのMain TextureをDefault-Particleに変えます。
なんだかもうそれっぽく出来てる!(^_^)v
ヒエラルキーの剣の軌跡エフェクトを移動と回転し、剣を振る軌道に合わせます。
ヒエラルキーのSwordSlashゲームオブジェクトを選択し、剣を振る軌道に合わせて移動と回転をしてください。
ただし現時点では地面にあるよりエフェクトを見やすくする為だけなので、適当にやって大丈夫です。
わたくしは以下のような位置と回転にしました。
この剣の軌跡エフェクトをVisualEffectGraphで回転させて剣の流れに合わせて軌跡が表示されているようにします。
そこでUpdate Particleコンテキストにパーティクルを回転させる処理を追加します。
Update Particleコンテキストを選択し、Spaceキーを押して検索窓にAdd Angleと入力し選択します。
Add Angleブロックは角度を追加するメソッドなのでUpdate Particleコンテキストにあると毎フレーム角度が追加されていくことになります。
ヒエラルキーでSwordSlashゲームオブジェクトを選択し、Local座標にしてシーンビューを見てみるとわたくしの場合はSwordSlashがキャラクターの前方に向けて回転すると剣を追いかけるように軌跡が描かれる感じになります。
つまりシーンビューでの緑色の軸(ローカルのY軸)を軸として回転させればいいことになります。
そこでAdd AngleのYに回転する角度を指定し回転させればいいことになります。
今回の場合はパーティクル(剣の軌跡)の生存期間中段々と回転速度が遅くなるような回転を加えます。
VisualEffectGraphウインドウの何もない所でSpaceキーを押して、検索窓にSample Curveと入力し選択します。
Curveのグラフ部分を押し、以下のような感じで最初は1、最後は0となるようなグラフを作ります。
Sample Curveオペレーターを選択し、Timeの入力ポートを左にドラッグし、検索窓にGet Ageと入力し選択します。
Get Attribute: age(Current)はパーティクル生成からの時間が得られるのでSample Curveではパーティクル生成時が1、パーティクル消失時が0となるような値が得られることになります。
Sample Curveのsポートを右にドラッグし、検索窓にmultiと入力し、Multiplyを追加します。
Multiplyは入力を掛けるのでSample Curveで得られた0~1の値に何らかの数値をかけて値を増やすことが出来ます。
とりあえずMultiplyのBに10を入力し、Multiplyの出力ポートをAdd Angleの入力ポートのYに接続します(全角度の入力ポートしか出てない時はAngleの左の矢印部分を押します)。
VisualEffectGraphウインドウのCompileかSaveボタンを押すと剣の軌跡エフェクトが回転するのを確認出来ます。
この回転を剣を振った時のアニメーションに合わせてある程度調整して合わせます。
ここでも完璧に合わせずある程度合わせるだけで大丈夫です。
Unityを実行し、キャラクターが剣を振った直後に一時停止(Ctrl+Shift+Pキー)し、ヒエラルキーのSwordSlashゲームオブジェクトを選択し、シーンビューで剣を振り始めの時に剣の軌跡のエフェクトの位置と回転を合わせます。
合わせたらUnityを実行したままヒエラルキーのSwordSlashゲームオブジェクトを選択し、インスペクタのTransformの右の3つの丸部分を押し、CopyからComponentを選択します。
コピーしたらUnityの実行をやめヒエラルキーのSwordSlashゲームオブジェクトを選択し、インスペクタのTransformの右の3つの丸を押し、PasteからComponent Valuesを選択します。
ここまで出来たらVisualEffectGraphのSet Lifetimeブロックのチェックを入れます(必要に応じて切り替えてください)。
キャラクターが剣を振った時に軌跡エフェクトを登場させる
剣の軌跡エフェクトは剣を振った時だけ登場させるのでスクリプトを使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.VFX; public class Character : MonoBehaviour { private CharacterController characterController; private Animator animator; private Vector3 velocity; [SerializeField] private float moveSpeed = 2f; private int speedAnimHash; private int attackAnimHash; [SerializeField] private VisualEffect visualEffect; // Start is called before the first frame update void Start() { characterController = GetComponent<CharacterController>(); animator = GetComponent<Animator>(); speedAnimHash = Animator.StringToHash("Speed"); attackAnimHash = Animator.StringToHash("Attack"); } // Update is called once per frame void Update() { if(characterController.isGrounded) { velocity = Vector3.zero; var input = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical")); if (!animator.GetCurrentAnimatorStateInfo(0).IsName("Attack")){ if (input.magnitude > 0f) { transform.LookAt(transform.position + input); animator.SetFloat(speedAnimHash, input.magnitude); velocity = moveSpeed * input.normalized; } else { animator.SetFloat(speedAnimHash, 0f); } } if(Input.GetMouseButtonDown(0) && !animator.GetCurrentAnimatorStateInfo(0).IsName("Attack") && !animator.IsInTransition(0) ) { animator.SetTrigger(attackAnimHash); } } velocity.y += Physics.gravity.y * Time.deltaTime; characterController.Move(velocity * Time.deltaTime); } void OnStartSwordSlash() { if (visualEffect != null) { visualEffect.SendEvent("OnStart"); } } void OnEndSwordSlash() { if (visualEffect != null) { visualEffect.SendEvent("OnStop"); } } } |
OnStartSwordSlashメソッドとOnEndSwordSlashメソッドはアニメーションイベントのレシーバーとして使用します。
OnStartSwordSlashは剣を振り始めた時、OnEndSwordSlashは剣を振り終わった時に実行するようにします。
剣を振り始めた時にOnStartイベントをVisualEffectGraphに送ります。
剣を振り終わった時はOnStopイベントをVisualEffectGraphに送ります。
インスペクタでCharacterスクリプトのVisualEffectGraphにヒエラルキーのSwordSlashをドラッグ&ドロップして設定します。
アニメーションイベントを作成する
アニメーションイベントを作成しましょう。
剣を振るアニメーションのインスペクタを表示し、Animationタブを選択します。
下にスクロールし、Events項目を探します。
下の赤く囲った部分をドラッグし剣を振り始めの位置を探し、上のアニメーションイベントの作成ボタンを押します。
Functionの所にOnStartSwordSlashと入力します。
剣の振り終わりのアニメーションイベントも同じように作成し、名前をOnEndSwordSlashとします。
先ほどのスクリプトはAnimatorコンポーネントを持つゲームオブジェクトに取り付けてあればこれらのアニメーションイベントを受け取ることが出来ます。
アニメーションイベントに関しては以下の記事も参照してみてください。
VisualEffectGraphにイベントを追加する
アニメーションイベントを受け取ったらOnStartやOnStopといったVisualEffectGraphにイベントを送るので、それらを受け取れるようにします。
SpawnコンテキストのStartとStopポートそれぞれからドラッグしEventコンテキストを追加し、Event NameにOnStartとOnStopと付けます。
これでとりあえずエフェクトが出来たので確認してみます。
よくよく見ると剣の軌跡とはなっていませんが、良さげな物が出来ました。(^_^)v
ShaderGraphを使ってエフェクトの見え方を調整
ここまででいい感じのエフェクトが出来ましたが、VisualEffectGraph用のShaderGraphを使ってエフェクトの見え方を調整してみたいと思います。
Assetsフォルダ内で右クリックからCreate→Shader Graph→VFX Shader Graphを選択し、名前をSwordSlashとします。
SwordSlash.vfxをダブルクリックして開きOutput Particle MeshコンテキストのShader Graphに今作ったSwordSlash.shadergraphを設定します。
SwordSlash.shadergraphをダブルクリックし開きます。
ここから少しややこしくなります。
ShaderGraphを使ってメッシュのマスク部分を作成していきます。
メッシュのマスクはPolar CoordinatesというUVの極座標が得られるものを使います。
極座標はUVの2次元座標を原点からの距離とX軸の正の向きからの角度で表したものでPolar Coordinatesを使うと与えた点からの極座標を得られ、その距離の成分を使ってマスクを作ります。
今回の場合であればその距離の成分を使ってエフェクトを一部隠して見えないようにします。
ShaderGraphウインドウの何もない所でSpaceキーを押して検索窓にPolarと入力し、Polar Coordinatesを選択します。
Outポートを右にドラッグし検索窓にSplitと入力し、選択します。
SplitのRポートが極座標の距離の成分になります。
SplitのRポートを右にドラッグし、検索窓にMultiと入力し、Multiplyを選択します。
このMultiplyは現時点でどうなっているかを確認する為に接続しただけです。
白が有効な部分で黒い部分は無効になります。
そこでこの白と黒を反転させます。
Multiplyを選択してDeleteキーを押し削除します。
SplitのRポートを右にドラッグし、検索窓にOne Minusと入力し選択します。
One Minusは値を1から引いて計算されます。
UVMapは0~1の間の値なのでOne Minusを通すと0の値は1に1の値は0になります。
つまり値が反転されるわけです。
One Minusを通すと以下のようなマスクが出来上がります。
あとでこの白と黒の割合を変化させますが、その前にClampを使って値を0~1に制限して値が大きくなってもこの領域が互い違いにならないようにします。
One MinusのOutポートを右にドラッグし検索窓にClampと入力しClamp: in(1)を選択します。
ClampのMinは0、Maxは1となっているのを確認します。
ClampのOutポートを右にドラッグし検索窓にPowerを入力し選択します。
Powerは累乗を計算出来ます。
PowerのBの入力値によってマスクの大きさを調整出来ます。
次に何もない所でSpaceキーを押して検索窓にSample Texture 2Dと入力し選択します。
Textureの所で試しにGrassのテクスチャを指定します。
Grassのテクスチャを設定したのはどの部分が見える状態なのかを確認する為です。
このSample Texture 2DのRGBAポートを右にドラッグし検索窓にMultiplyと入力し選択します。
先ほど作ったPowerのOutポートを今作ったMultiplyの入力ポートのBにドラッグし接続します。
Multiplyのプレビューを見てわかる通りテクスチャの中心が見え、外に遠ざかる部分は黒く見えない状態になります。
ここまできたらSample Texture 2DのテクスチャをDefalut-Particleに変更します。
最後のMultiplyのOutポートを右にドラッグし検索窓にSplitと入力し選択します。
SplitのAポート(アルファ)をドラッグし、FragmentのAlphaポートに接続します。
さらにFragmentのBase Colorを赤色にし、剣の軌跡が赤色になるようにします。
これで完成です。
最終的な剣の軌跡用のShaderGraphの全体図は以下のようになっています。
シンプルなグラフに変える
実は今回Base Colorに最終的なRGBの値は接続せずAlphaにAの値だけを接続しているので、アルファの値だけを使うならばもっと簡単なグラフに出来ます。
中身はほぼ同じなので解説は省きますが、テクスチャをClampを使って0~1の間に制限して白黒にし、白い部分が有効で黒い部分が無効なのでそれをFragmentのAlphaに接続するという感じです。
だいぶわかりやすいですね。(^^)/
今回はPowerの入力Bの値を2.5にしてみました。
最終的な調整
Unityを実行してSwordSlashゲームオブジェクトの位置と回転を剣を振るアニメーションに合わせます。
剣の軌道を確認し剣の軌跡エフェクトが合うようにします。
SwordSlashゲームオブジェクトの調整とともにSwordSlash.vfxのSet Size、Set Lifetime、Add AngleのYに接続しているMultiplyのBの値を調整していきます。
わたくしの場合はSet Lifetimeを0.1、MultiplyのBを65としました。
UVMap
今回Blenderで作成したトーラスを剣の軌跡のメッシュとして使用しましたが、デフォルトで作成されたUVMapを確認したいと思います。
UnityのProBuilder用に変換する
まずは剣の軌跡用に取り込んだメッシュをヒエラルキーに配置します。
ヒエラルキーのトーラスゲームオブジェクトを選択した状態でProBuilderウインドウを開きます(UnityメニューのTools→ProBuilder→ProBuilder Window)。
ない場合はProBuilderをPackage Managerからインストールしてください。
ProBuilderウインドウが開いたら、再度ヒエラルキーのトーラスゲームオブジェクトが選択されているのを確認してからProBuilderのProBuilderizeを押します。
ProBuilderがアイコンモードかテキストモードかで表示が変わります。
ProBuilderizeをするとヒエラルキーのトーラスがProBuilderで使えるようになります。
次にUVEditorを押します。
UVEditorウインドウが開きます。
UVMapは上のようになっています。
UnityでDefault-ParticleテクスチャをBase Mapに設定したマテリアルを作成しヒエラルキーのトーラスにドラッグ&ドロップして設定してUVEditorで確認してみます。
上のような感じでテクスチャとメッシュが割り当てられています。
UVMapの各面を移動や回転、拡大縮小をさせてテクスチャの割り当てを変更すると剣の軌跡のエフェクトの見栄えも変わります。
ちなみにProBuilderでトーラスを作成し、UVEditorで開くとデフォルトでは以下のような感じのUVMapになっています(変更しちゃっているかも・・・)。
シーンビューとUVMapを確認しながらUVMapの面の位置やサイズ、頂点の移動等を行ってテクスチャの割り当てを変更していきます。
UVEditorのシーンビューのロック機能を使うとシーンビューのメッシュを操作して割り当てを変更することも可能です。
ProBuilderに使い慣れてないのでわかりませんが、ここから割り当てを変更するのは結構しんどそう・・・(^_^;)
UVEditorに関してはマニュアルとそこからリンク先を辿るとわかりやすいかもしれません。
終わりに
今回はシンプルな剣の軌跡エフェクトを作成しましたが、参考にさせて頂いた動画だともっと豪華なエフェクトが作成されています。
エフェクトに興味がある方は色々試してみると面白いかもしれません。
今回はVisualEffectGraphでパーティクルを回転させて軌跡のように見せましたが、ShaderGraphでテクスチャのUVのOffsetを操作してテクスチャを動かして軌跡のように見せるという事も出来ます。
やり方は色々ありますね。(´Д`)