今回はUnityで炎の剣を作っていきます。
使用するUnityのバージョンは2021.3.3f1(2021.3.7f1でも動作)で
UnityのProBuilderの5.0.4
UnityのVisualEffectGraphの12.1.6
UnityのShaderGraphの12.1.6
を使用しています。
またプロジェクトは3DのUniversalRenderPipelineのテンプレートで作成したものを使用します。
その他には画像編集ソフト(WindowsのペイントでもOK)も使用します。
また、アセットストアでUnityのStandardAssetsもダウンロードしておいてください。
スタンダードアセットにある炎のテクスチャを使用します。
出来上がったものは以下のような感じになります。
パーティクルの見栄えの問題や、剣を振っても炎のパーティクルが剣に張り付いたままという問題はありますが、とりあえず剣のオブジェクトをProBuilderで作成し、ShaderGraphを使って剣の刀身部分を光らせ、VisualEffectGraphを使って炎のパーティクルを表示するということまでは出来ます。
ProBuilderを使って剣のオブジェクトの作成
最初にProBuilderを使って剣のオブジェクトを作成していきます。
ProBuilderに関しては以下の記事を参照してください。

剣のオブジェクトの作成は他の3DCG作成ソフトを使って作成したものや、アセットストアで手に入れたものがあればそちらでも構いません。

既に剣のモデルとテクスチャがある場合はProBuilderを使った剣のオブジェクトの作成の項目は飛ばしてください。
剣の形状を作成する
まずはProBuilderを使って剣の形状を作成していきます。
ProBuilderのNew Shapeを押し、シーンビューでCreate ShapeをCubeにしてシーンビュー上でマウスの左ボタンを押した後、ドラッグして適当な大きさになったらマウスの左ボタンを押して確定し、次はマウスをドラッグして高さを決めたら再びマウスの左ボタンを押してCubeを作成します。
今回はCreate ShapeのCubeの設定のSizeに直接数値を入力して形状を変えるのでシーンビュー上では適当なサイズのCubeが出来ればいいです。
シーンビュー右下のCreate ShapeのCubeのSizeでXとZを0.02、Yを1とします。
これで大雑把な剣の形が出来ました。
面選択モードにして先ほど作ったCubeの下の一つの面を選択します。
Extrude Facesのメニュー右上の歯車をAltキーを押しながらマウスの左ボタンを押すことでメニューを表示します。
出てきたOptionウインドウでExtrude ByをFace Normal、Distanceを0にし、Extrude Facesボタンを押します(何回も押さないでください)。
Extrude Facesは面の押し出しをするメニューで、Distanceを0としたことでその場に面が押し出されます。
Optionsウインドウを閉じ、シーンビューでScaleツールもしくはRキーを押し、中央の灰色のCube状のアイコンを使って全体を刀身よりも少し大きくなるようにサイズを変更します。
さらにExtrude Facesボタンを押し、そのままMoveツールもしくはWキーを押して矢印を使って下に伸ばします。
刀身の付け根部分から下に面が伸びてしまう場合はExtrude Facesが実行されなかった可能性があるので、実行し再度矢印を使って下に伸ばしてみてください。
今下に伸ばした面の横の2面をCtrlキー(Shiftキーの方がいいかも?)を押しながら選択し、Extrude Facesを押し、ScaleツールもしくはRキーを押して今度は横だけに伸ばすので青いCubeアイコン(場合によっては色が違うかも)を使って横に伸ばします。
持ち手部分を作ります。
下の面を選択し、Extrude Facesを押しMoveツールの矢印を使って下に伸ばします。
以下のような形でなんとなく剣の形状が出来てきました。
刀身の形状を作る
剣の全体像は出来たので、次は刀身の形状を作っていきます。
面選択モードにして、剣の刀身の一つの面を選択し、Select Face Ringを押して刀身の面をぐるりと選択します。
次にSubdivide Facesを押して面を分割します。
刀身部分の面が分割されました。
剣先の面を選択しExtrude Facesの右上の歯車をAltキーを押しながらクリックし、OptionsウインドウでDistanceに0.05を入力しExtrude Facesボタンを押します。
頂点選択モードにし、押し出された先の一つの頂点を選択してから、Set Hidden Element SelectionをOnにし、剣先全ての頂点をマウスドラッグして選択します。
剣先の全ての頂点が選択出来たらCollapse Verticiesを押してそれらの頂点を一つの頂点にまとめます。
以下のように剣先が出来ました。
次に刀身の頂点をいくつかまとめてとがった部分を作成します。
刀身の根本部分の3つの頂点を選択し、Collapse Verticiesを押します。
反対側も同様に3つの頂点を選択しCollapse Verticiesを押します。
刀身の他の部分も同様に行ってください。
刀身で合計6か所あります。
全部行うと以下のように尖った剣になります。
剣は尖りましたがより鋭くする為に刀身の幅を狭めます。
刀身の根本部分の2個の頂点をCtrlキー(Shiftキーの方がいいかも?)を押しながら選択し、さらに刀身の中間部分の2点、剣先の2点も選択します。
頂点は剣の刀身の正面と反対側の頂点の6つになります。
選択したらScaleツールもしくはRキーを押した後、青いCubeアイコンで刀身の幅を調整します。
これで剣のオブジェクトが出来ました!
ヒエラルキーのCubeの名前をFireSwordに変更しておきます。
UVEditorでUVMapの調整
剣の形が出来たので次は剣のUVMapを調整していきます。
UVMapは剣の面のどの部分がテクスチャのどの部分に対応しているかの情報になります。
なので色を塗りやすいようにUVMapを整列していきます。
UVEditorを押します。
UVEditorウインドウが開き、現時点でのUVMapが表示されます。
シーンビューで選択した面とUVEditorが連動しているのでどちらかで動かしたい面や点等を選択し、移動等を行って調整します。
まずは刀身の前面をシーンビューで選択します。
UVEditorに移動し矢印を使って白い四角の中に移動させます。
UVEditorのActionsのProject UVsのBoxを使うと四角い形状に変化してくれたり、EditのCollapse UVsで頂点をまとめたり、Split UVsで繋がっているUVを切り離したり、Fit UVsで白い四角の枠の中にフィットするようにUVを収められたりします。
自由にわかりやすいUVMapとなるように移動やスケールの変更などもしてください。
今回は以下のような感じのUVMapにしました。
動画の最後の方を見るとわかりますが、UVMapである面を選択するとそれに対する3Dの面がシーンビューで確認出来ます。
つまり、このUVMapが3Dの剣の面を2Dに割り当てたものになるので、この画像をデスクトップに出力し、ペイントで色を塗っていけば、3Dの剣の各面に色が塗られることになります。
UVMap画像の出力
出来たUVMap画像を出力します。
UVEditorウインドウの上のカメラアイコンを押します。
出てきたウインドウで以下のように設定し、Save UV Templateボタンを押してデスクトップにファイルを出力します。
剣のテクスチャを作成する
出力した剣のUVMapをペイント等で開きます。
この緑色の線で囲まれた部分に色を塗っていきその画像をUnityに取り込んでマテリアルに設定してそれを剣のマテリアルとすれば剣の対応する面に色が塗られることになります。
UnityのUVEditorで3Dの剣と2DのUVMapの対応を確認しながら色を塗っていきます。
上のように持つ部分は茶色、持つ部分と刀身の間は黄色、刀身は灰色というような感じで塗りました。
ここで注意が必要なのがUVの割り当ての境界である緑色の線も色を塗らないと反映した時に3Dの剣に緑色の線が出てしまいます。
再度塗りなおしたものが以下のようになります。
次にUnityのAssetsフォルダに今塗り終わった画像をドラッグ&ドロップして取り込みます(デスクトップの画像ファイルは後で使いますので削除しないでください)。
またAssetsフォルダ内で右クリックからCreate→Materialを選択し、名前をFireSwordとします。
FireSwordマテリアルを選択し、インスペクタのBase Mapの左側に先ほど取り込んだfireswordテクスチャを設定します。
次にヒエラルキーのFireSwordゲームオブジェクトにFireSwordマテリアルをドラッグ&ドロップして設定します。
シーンビューで確認するとFireSwordゲームオブジェクトに色が塗られたのを確認出来ます。
細かく確認すると接合部分等で色が塗られていなかったりするかもしれません。
今回の場合UVMapの線ギリギリで色を塗っているからで、元々のUVMapの線を少しはみ出す感じで色を塗ると解消されます。
他の色を塗った境界とかぶらなければ以下のような塗り方でも出来ます。
ShaderGraphを使って刀身の色を変える
剣のオブジェクトが出来ましたが普通の金属の剣となっています。
そこでシェーダーグラフを使って剣の刀身のみを赤い色に変更したいと思います。
Assetsフォルダ内で右クリックからCreate→Shader Graph→URP→Lit Shader Graphを選択し、名前をFireSwordとします。
出来たファイルをダブルクリックしてShaderGraphウインドウを開きます。
左上のShader Graphsという部分をダブルクリックしてMyShaderGraphsに変更します。
左上のSave Assetボタンを押してシェーダーグラフを保存します。
現時点で剣のゲームオブジェクトであるFireSwordのマテリアルにはFireSwordマテリアルを設定していますが、このマテリアルのシェーダーにはUniversal Render Pipeline/Litが設定されています。
そこでAssetsフォルダにあるFireSwordマテリアルを選択し、インスペクタのShaderでMyShaderGraphs→FireSwordを選択します。
FireSwordシェーダーグラフではFragmentのBase Colorにデフォルトで灰色が設定されている為、剣のゲームオブジェクトが全て灰色になります。
Universal Render Pipeline/Litシェーダーの時と同じように剣に自前のテクスチャの色を反映します。
FireSwordシェーダーグラフウインドウに戻り、Blackboardの+を押し、Texture 2Dを選択して新しい、名前をMainTextureとしてプロパティを作成します。
出来たMainTextureプロパティを何もない所にドラッグ&ドロップして配置し、ポートを右にドラッグして出てきたウインドウの検索窓でSampleと入力しSample Texture 2Dノードを選択します。
Sample Texture 2DノードのRGBAポートをFragmentのBase Colorに接続します。
接続したらウインドウ左上のSave Assetボタンを押して保存します。
BlackboardのMainTextureプロパティを選択し、Graph Inspector(表示されていない場合は右上のGraph Inspectorボタンを押してください)のExposedにチェックが入っているのを確認してください。
Exposedにチェックが入っているとマテリアルのインスペクタでMainTextureプロパティの値を設定することが出来るようになります。
AssetsフォルダのFireSwordマテリアルを選択し、インスペクタのSurface InputsのMainTextureのSelectボタンを押してFireSword.png(剣のベースのテクスチャ)を設定します。
設定するとシーンビューでは以下のように表示されます。
これで通常の剣が出来たので、次は剣の刀身部分を赤く発光させていきます。
剣の刀身部分だけを発光させるので剣の刀身部分だけをマスクするようなテクスチャを別途用意します。
パソコンのデスクトップにあるfiresword.pngファイルをペイントで開きます。
シェーダーグラフでマスクを使用する時に白い色の部分が有効、黒い部分が無効な部分となりますので、剣と刀身部分を白色、その他の部分は黒色で塗りつぶします。
塗りつぶしの順番としては剣の刀身以外を黒色でまず塗りつぶし、その後、刀身部分を白色で塗りつぶします。
maskという名前で保存し、UnityのAssetsフォルダにドラッグ&ドロップして取り込みます。
マスクが出来たのでFireSwordシェーダーグラフを開き、マスクを使って刀身部分を赤く発光させます。
Blackboardの+を押しTexture 2Dプロパティを作り、名前をMaskとします。
Maskを何もない所にドラッグ&ドロップし、ポートをドラッグして出てきたウインドウの検索窓にSampleと入力しSample Texture 2Dノードを選択します。
ここまでは以下のようになります。
メインのテクスチャサンプルとマスクのテクスチャサンプルを掛け合わせることで、白い色の部分だけを抜き出します。
MainTextureを接続したSample Texture 2DノードのRGBAポートをドラッグし、出てきたウインドウの検索窓にmultiと入力し、Multiply(A)ノードを選択しAポートに接続します。
Maskを接続したSample Texture 2DノードのRGBAポートをドラッグし、Multiplyの入力Bのポートに接続します。
現時点でどうなっているかをプレビューで確認する為にプロパティのDefaultにテクスチャを設定します。
MainTextureプロパティとMaskプロパティをそれぞれ選択し、Graph InspectorのDefaultにfiresword.pngとmask.pngを設定します。
プロパティのDefaultを設定するとシェーダーグラフのプレビューに経過が表示されます。
経過を見てみると刀身部分だけが抜き取られているのがわかります。
あとはこの抜き取った部分を赤色にします。
MultiplyのOutポートをドラッグし、出てきたウインドウの検索窓にMultiplyを入力し選択します。
何もない所でSpaceキーを押して、出てきたウインドウの検索窓にColorと入力しInput→BasicのColorを選択します。
ColorのOutポートをドラッグし、二つ目のMultiplyの入力Bに接続します。
二つ目のMultiplyのOutポートをドラッグし、FragmentのEmissionに接続します。
Emissionに接続するとその部分が自ら発光しているようになります。
今回の場合はMainTextureの刀身部分をMaskテクスチャで切り抜いた部分に赤色を掛けていますが、完全な赤色ではありません。
完全な赤色にするにはMaskテクスチャを繋いだSample Texture 2DノードのRGBAの出力をMultiplyでColorと掛けてEmissionに接続します。
今回は赤色っぽく出来ればいいのでそのままいきます。
これでシーンビューの剣の刀身部分だけが赤っぽく発光します。
試しにライトを消し、環境光もなくすと以下のような感じで自ら光ります。
シェーダーグラフでの処理はここまでになります。
VisualEffectGraphを使って剣から炎を出す
剣の刀身部分が発光するようになりましたが、炎の剣というよりはレーザーブレードといった感じです。
そこでVisualEffectGraphを使って剣の回りに炎のエフェクトを登場させて炎の剣っぽくしていきます。
Assetsフォルダで右クリックからCreate→Visual Effects→Visual Effect Graphを選択し、名前をFireEffectとします。
ヒエラルキーのFireSwordゲームオブジェクトにFireEffect.vfxをドラッグ&ドロップして子に配置します。
FireEffectゲームオブジェクトのTransformのPositionはXとZは0、Yは-0.248としました(適宜変更してください)。
FireEffect.vfxをダブルクリックしてVisualEffectGraphのウインドウを開きます。
まずは出力設定でFlipbookを使って複数のテクスチャを出力出来るようにします。
Output Particle QuadでUV ModeをFlipbook、Blend ModeをAdditive、Main TextureにAssets/Standard Assets/ParticleSystems/Textures/ParticleFlamesSheetを設定します。
ParticleFlamesSheetでは複数の炎がひとつの画像内にあり、横に8、縦に4個ありますので、Flip Book Sizeのxに8、yに4を入力します。
Orient: Face Camera PlaneとSet Color over Lifeは選択してDeleteキーを押して削除します。
Set Size over Lifeはパーティクルが生存している間のサイズの設定なので、炎パーティクルが現れてから段々小さくなるようにSizeのグラフを右肩下がりに変更します。
グラフの左の点(timeが0)を右クリックからEdit Keyを選択し、Valueを0.4、グラフの右の点(timeが1)を右クリックからEdit Keyを選択し、Valueを0とします。
ここまでは以下のようになります。
Flipbook(パラパラ漫画)の出力設定をしましたが、その切り替えをしていない為にずっと同じ炎だけが表示されています。
そこでUpdate Particleを選択し、Spaceキーを押して出てきたウインドウからFlipbook→Flipbook Playerを選択します。
Frame Rateは32にしました。
これで炎が揺らめいているようになりました。
次はSpawnコンテキストのConstant Spawn RateのRateを50にして定期的に50個のパーティクルを生成するようにします。
またInitialize ParticleコンテキストのCapacityを50にし、50個のパーティクルが同時に表示されるようにします。
InitializeParticleコンテキストでSpaceキーを押して、出てきたウインドウの検索窓にSet Positionを入力し出てきた中からSet Position(Shape: AABox)を選択します。
Set Position(Shape: AABox)ブロックを選択し、シーンビューで白いボックスの形状を操作して以下のようなボックスの形状にし、その範囲内でエフェクトが発生するようにします(ボックスの形状を分かりやすくする為にSpawnコンテキストのConstant Spawn Rateは一時的に無効にしています)。
炎エフェクトはこのボックス内で発生するようになります。
次にSet Position(Shape: AABox)ブロックを選択した状態でSpaceキーを押し、出てきたウインドウの検索窓にSet Velocityと入力しSet Velocity(Attribute Set)を選択します。
Set Velocityブロックをドラッグし、Set Position(Shape: AABox)の下に位置するように移動させます。
さらにVelocityがL(ローカル)であるのを確認し、yに0.4を入力し、パーティクルが発生した位置から剣先の方向に速度を発生させます。
これで以下のような感じになりました。
エフェクトを違う角度から見ると平面になる
炎のエフェクトが良く出来たような気がしますが、剣の先側から剣の根元を見たり、剣を横から見ると、以下のように炎のエフェクトが平面になっています。
これは元々平面の画像を表示しているので立体的にみると平面の部分が分かってしまう為です。
というわけで少し誤魔化します。
Output Particle Quadコンテキストを選択し、Spaceキーを押して出てきたウインドウの検索窓にOrientと入力し、Orient: Fixed Axisを選択します。
UpがLなのを確認し、yに1を入力します。
これで剣先にの方向を軸にしてエフェクトが回転するようになり剣を横から見ても平面が表示されません。
ただ、剣先から剣元を見るとやはり平面に見えてしまいます。
そこで誤魔化し炎エフェクトを追加します。
FireEffect内にもうひとつSpawnコンテキスト、Initialize Particleコンテキスト、Update Particleコンテキスト、Output Particle Quadコンテキストを追加します(各コンテキストは何もない所でSpaceキーを押す事で追加出来ます)。
各コンテキストに追加するブロックはほとんど同じです。
Constant Spawn RateとInitialize ParticleのCapacityを100にします。
Set Position(Shape: AABox)を選択し、シーンビューで刀身の根本付近にボックスがくるようにします。
Set Velocityのyは0.3と若干速度を落とします。
Output Particle Quadを選択し、Spaceキーを押して出てきたウインドウの検索窓にSet Sizeを入力し、Set Size over Lifeを追加します。
Sizeのグラフでtime0の点を右クリックからEdit Keyを選択し、Valueを0.1にします。time1のValueは0にします。
Output Particle Quadを選択し、Spaceキーを押して出てきたウインドウの検索窓にorientと入力し、Orient: Face Camera Planeを選択します。
Orient: Face Camera Planeにするとエフェクトがカメラに対して回転するようになるので、平面が見えなくなります。
これで誤魔化し炎エフェクトが出来ました。
最初に作った炎エフェクトの平面部分を今作ったカメラに対して回転する炎エフェクトでなるべく見えなくしています。
別のやり方
誤魔化しのパーティクルを追加するのではなく、パーティクルの到達点を変更するやり方で平面部分を目立たなくするやり方もあります。
Output Particle Quadコンテキストを選択し、Spaceキーを押して出てきたウインドウの検索窓にConnectと入力し、Connect Target(Orientation)を選択します。
Connect Targetブロックを選択し、シーンビューでターゲットの位置を剣先に移動し、パーティクルが到達するターゲット位置を決定します。
炎のパーティクルの出現位置を調整する為に、Initialize ParticleコンテキストのSet Position(Shape: AABox)の位置もシーンビューで調整してください。
以下のような感じになりました。
VFXのウォームアップ
炎の剣が出来ましたが、炎のエフェクトが出現するまでに数秒かかります。
VisualEffectGraphのシミュレーションを事前にしておいてVFXを開始した時に直ぐに実行出来るように設定しておきます。
AssetsフォルダのFireEffect.vfxファイルを選択し、インスペクタでPreWarm Total Timeを2、PreWarm Step Coutを40、PreWarm Delta Timeを0.05に変更します。
Prewarm Total Timeはシミュレーションをするトータルの時間、PreWarm Step Countはシミュレーションのステップ数、PreWarm Delta Timeはシミュレーションする時のデルタ時間を指定します。
シミュレーションに正確なデルタ時間を使用したい場合はPreWarm Total TimeとPreWarm Step Countを変更するのではなくPreWarm Delta Timeを変更すると良いようです。
エフェクトがうまく表示されない場合は数値を変更してみてください。
キャラクターに剣を持たせ確認してみる
炎の剣が出来たので後は剣を振るキャラクターの手に持たせ確認してみてください。
剣のピボット点を変更する
ここまでで剣のピボット点(オブジェクトの回転の基点)が変な位置にあるので、剣のグリップ部分に移動した方が便利な事があります。
そこで剣のオブジェクトのPivot点を変更します。
FireSwordゲームオブジェクトの子のFireEffectを一番親の階層にドラッグ&ドロップしてFireSwordとの親子関係を解消し、TransformのPosition、RotationのXYZを全て0、ScaleのXYZを全て1にします。
オブジェクトのToggle Tool Handle PositionをPivotに変更しPivot点を使った位置を確認出来るようにし、ヒエラルキーのFireSwordゲームオブジェクトを選択します。
シーンビューで剣のオブジェクトのピボット点にしたい位置をワールド座標のXYZが0の位置に移動させます。
わたくしの場合はグリップと刀身の間ぐらいをXYZの0の位置に移動させました(剣のオブジェクトのTransformのPositionの位置は現時点で0にはならない)。
ヒエラルキーのFireSwordゲームオブジェクトを選択した状態でProBuilderウインドウを開き、Freeze Transformを押します。
Freeze Transformを押すとオブジェクトのPivot点がワールド座標のXYZの0の位置に移動します。
もしFreeze Transformボタンが押せない場合はProBuilderizeを押してProBuilderで使えるようにしてからFreeze Transformを押してください。
これでPivot点が剣の刀身とグリップの間ぐらいに移動し、TransformのPosition、RotationのXYZが全て0、Scaleが全て1になりました。
あとはFireEffectゲームオブジェクトをFireSwordにドラッグ&ドロップして元に戻します。
FireEffect自身の位置をずらすか、FireEffectのInitialize ParticleのSet Positionブロックの位置をずらすなどの必要が出てきます。
キャラクターの手に剣を持たせるのもグリップ部分にピボット点があるので操作しやすくなりました。
剣の持たせ方は以下の記事も参考にしてください。

これで炎の剣が出来ました。
終わりに
Unityの色々な機能を使って炎の剣を作成しました。
完成度としてはまだまだですが、Unityの色々な機能を使ってオブジェクトの作成からエフェクトの作成までの基本的な事が出来たので良かったです。
今回の場合はFireSwordの子にFireEffectを配置しているのでパーティクルが剣の動きに合わせて動いてしまうので、以下の記事のようにした方が炎のパーティクルが自然な感じになるかも?

色々試してみてください。