はじめに
勉強で作っていた改造版サンプルプロジェクトの自慢をばと思い、初めての参加です。
また、各章にナンバリング振ってますが、何の意味もないです。
初級編に関しては独立しているので興味ある所だけやるのもよしです。
注意点
以降UnrealEngineのことをUEと書きます。
また、以下の基本的な操作ができることを前提としています。
- サンプルプロジェクトを動かしたことがある
- コンテンツブラウザ、レベル、アクタなどの基本用語がわかる
- アクタの配置やBlueprintで音を鳴らすなどの単純なものであれば作れる
- ただし、NiagaraやChaos Destructionなどはふわっと存在を知っていればOK
対象
何か作りたいけどアイデアない人
基本操作は覚えたけどそれ以上先に進めない人向けです。
全部サンプルプロジェクト内のアセットだけで完結させるので、お気軽に試してみてくださいね!!
最終結果
必要なもの
- Unreal Engine 5
目次
- 導入:サンプルプロジェクトを作る
パーツを作るフェーズ
- 初級1:マテリアルをいじってみる(Lumen、Blueprint)
- 初級2:ものを砕いてみる(Chaos Destruction)
- 初級3:UIでアニメーション(Sequencer、UMG)
- 初級4:雨を降らせてみる(Niagara)
組み込み例
- 中級1:オブジェクトが破壊されたらディゾルブ表現でフェードアウトしてみる(Blueprint)
- 中級2:リスポーンする(Blueprint)
ちなみに上級がないのは仕様です。
決して間に合わなかったわけでは。。。
導入:サンプルプロジェクトを作る
所要時間:5~10分
詳細
FirstPersonを好きなパスに作ってもらえれば完了です。画像では「C++」を選択していますが、「Blueprint」でも問題ありません。
「最終結果」では明るさを下げてLumenの輝きを強調してます。
下の値を調整することで明るさを変更できますが、見づらくなるので以降では初期値を使用します。
レベル上のDirectionalLightを選択し、DetailsよりIntensityの項目を小さくすると暗くなります。
初級1:マテリアルをいじってみる(Lumen、Blueprint)
所要時間:5~10分
Lumenを設定する
まず初めにプロジェクト設定からLumenが有効になっていることを確認します。 負荷が高い場合などはLumen以外を設定することで光源に関する処理が軽減される可能性があります。コンテンツブラウザから右クリックでマテリアルを作成します。
マテリアルをダブルクリックするとBlueprintのような設定画面が表示されます。
右クリックをして「constant」と検索をかけて「Constant4Vector」を追加します。
画像のように既にあるEmissive Colorにノードをつなげると「Constant4Vector」のカラーが適用されます。
所要時間:20~30分
ディゾルブを実装する
新たに「DissolveMaterail」アセットを作ります。
次にResultノード(同名のマテリアル名にした場合は「DessolveMaterial」ノード)を選択した状態で詳細ウィンドウの「Blend Mode」を「Masked」にします。
次に「TextureSample」というノードを追加します。
詳細ウィンドウの「Texutre」に「T_Perlin_Nose_N」を追加します。
このテクスチャの模様でフェードアウトorフェードインします。
完成したらいろいろ試してみるとバリエーションが増えますね!!
※「noise」と検索しても出てこない場合
次にフェードインをするための時間を取得する関数を追加します。
「Time」と選択し、ノードを作り、詳細から「Period」にチェックを入れて「1.0」をセットします。
この値より大きな値になると0に値が戻ります。
Aについて
「Constant4Vector」ノードで色を指定します。今回は光らせたいので「Emissive Color」につなげていますが、「Base Color」につなげると光らせないといったこともできます。
Bについて
フェードインの実装になります。
「1-x」は「OneMinus」というノードです。
名前の通り入力をxとして1から減算します。
このノードを除くとフェードアウトになります。
「Step」はY<Xのとき1をそれ以外の場合は0を出力します。
Cについて
Emissive Colorは前述の通り、色以外に光り輝かせるノードになります。
輝度で輝きを調整できます。
Opacity Maskは0~1の値をとり、1の場合は不透明、0は透明として画像を透過してくれます。
所要時間:10~20分
ディゾルブマテリアルを拡張する(外部からパラメータを設定する)
以下の変化をつけられるように修正してみます。- 色を指定できるようにする。
- フェードイン&フェードアウトに対応する
- アニメーションの速度を変更可能にする
1. アニメーションの速度を変更可能にする
外部に公開するパラメータは定数ノードを右クリックで「Convert to Parameter」とすると外部で設定できます。
色を設定するノードを上記のようにパラメータ化すると外部から設定できるようになります。
2. フェードイン&フェードアウトに対応する
「1-x」の箇所を変更します。
xは0から増加するので「x」を入力とすればよさそうです。
しかしマテリアルでif分を使うのはパフォーマンスの側面で避けるべきなので、
絶対値を使います。
一度、正しいか見てみましょう。
Fadeに0に設定すると「Substract」(引き算)で「0-x」となりその後絶対値を取るため「x」となり、フェードアウトになりますね。
逆にFadeに1を設定すると「1-x」の絶対値を取ることになり、フェードインになります。
3. アニメーションの速度を変更可能にする
時間を取得する関数に倍率を乗算するとできます。
注意として倍率がかかることで最大値が1ではなくなってしまうため、最小値を取るようにしています。
※最小値を取る理由
Aが1より小さい場合は1との最小値をとるとAが出力されます。
Aが1より大きい場合は1との最小値をとると1が出力されます。
一見直感的ではないですが、このように最大値を設定したい場合は最小値を計算すると良いです。
パラメータの設定方法
ブループリントで「Set Scalar Parameter Value on Materials」ノードにパラメータ名と値を指定します。
色の指定の場合はベクトルなので「Set Scalar Parameter Value on Materials」ノードを使って指定します。
初級2:ものを砕いてみる(Chaos Destruction)
所要時間:5~10分
所要時間:10~20分
オブジェクトを分割する
今回の分割方法は均一に分割したいので「Uniforom」を選択します。次に分割数を設定します。
分割数が増えるほど処理負荷に大きな影響を与えます。
「Uniform Voronoi」の項目にある「Min Voronoi Sites」を20、「Max Voronoi Sites」を100に設定します。
その後、最下部にある「Fracture」ボタンを選択すると分割がされます。
すると、Level上のアクタが分割されているのが分かります。
「Fracture」のウィンドウでの設定は異常なので「Selection Mode」に設定します。
このままPIEを起動すると以下のようにデバッグ用の表示がされた状態になります。
表示の設定は対象のアクタを選択し、詳細ウィンドウより「General」の項目にある「Show Bone Colors」のチェックを外せば切り替えることができます。
所要時間:20~30分
銃で破壊できるようにする
今のままでは銃で撃ったとしても破壊されません。 これは玉の衝突判定設定が原因となっています。弾のアセットは以下に配置されています。
アセットを開き、衝突判定を担っている「CollisionComponent」を選択します。
詳細ウィンドウから「simulate Physics」にチェックを入れます。
それ以外にも衝突判定についてどのような挙動をするか設定する必要があります。
「Collision Enabled」を「Collision Enabled (Query and Physics)」に設定します。
次に弾が衝突した際には盛大に破壊したいので弾の質量を重く設定します。
また、壊れやすくしましょう。
「オブジェクトを分割する」で作ったアセットの詳細を開きます。
「damage」と検索し、「Damage Threshold」の0番目を「0.1」にします。
これによって壊れやすいオブジェクトになります。
※Damage Thresholdが複数ある理由
オブジェクトの分割を行った際に下部にある「Level」と紐づいています。
ダメージによって壊れ方を段階的に変えたい場合には複数回、分割をしてそれぞれ壊れやすさを設定することもできます。
初級3:UIでアニメーション(Sequencer、UMG)
所要時間:5~10分
「User Widget」アセットを作成する
コンテンツブラウザから画像のように「Blueprint」を選択します。選択すると「Pick Parent Class」ウィンドウが表示されます。
この項目はBlueprintで様々な機能を実装するにあたってベースとなる基盤を選択することができます。
今回は「User Widget」を選択します。
アセットを開くと次のような画面が表示されていれば成功です!!
所要時間:5~10分
文字を配置する
まずは複数のパーツを配置できるようベースとなる「Canvas Panel」をドラッグ&ドロップで配置します。正しく追加できていると左下の「Hierarchy」に「Canvas Panel」が追加されます!!
今回は文字を配置するために「Palette」で「Text」を検索してドラッグ&ドロップで追加します。
すると、テキストが配置されるだけではなく、星マークが付きます。
このマークは基準点となっており、この位置からの相対位置に文字が表示されます。
例えば、PCとipadなどウィンドウサイズが異なる場合に崩れなくなるので適切に設定することをお勧めします。
今回は中心に表示させるようにしてみましょう。
対象をクリックして「Anchors」から中心に配置しそうなものを選択します。
あとは相対位置を設定するだけです。
中央であれば相対位置を0にすればいいので「Position」を原点にします。
すると、左上に基準点が来てしまうので、「Alignment」でずらします。
テキストの範囲の中心を基準とするため0.5を設定します
※(x = 1、y = 0)にすると右上に来ます。
所要時間:5~10分
ゲームで表示させる
表示させるにはBlueprintで簡単な実装が必要です。 といっても二つだけです。 1. 対象のUserWidgetを生成する 2. 画面に配置するまずは「Level Bluepirnt」を開きます。
「Construct」と調べて「Construct Object from Class」ノードを作ります。
「Class」に対象のクラス(『「User Widget」アセットを作成する』で作成したアセット名)を指定します。
今回はゲーム開始時から表示させたいので「BeginPlay」イベントに接続します。
次に表示をさせるために「Return Value」から「Add to Viewport」を選択します。
最終的に以下の画像のようになっていれば完成です!!
ゲームを開始するとカメラを移動させても中央に文字が表示されます。
所要時間:20~30分
文字をフェードイン・フェードアウトさせる
文字が「Text Block」では味気ないので、Detailsウィンドウより「Content」→「Text」の文字を変更します。
まずは、文字の下にあるラインを用意します。
「Palette」ウィンドウで「Image」を検索し画像のように配置します。
位置やアラインメントについては次の画像のように設定しました。
※Anchorは中央にしています。
ウィンドウの下部分にあるアニメーションウィンドウから「+Animation」を押して追加します。
右側のタイムライン上にある縦線が左から順にアニメーション開始時刻、再生時刻、アニメーション終了時刻です。
今回は1.5秒のアニメーションを実装するため一番右側の縦線を1.5の位置に移動させます。
次に文字を選択して「+Track」を選択します。
すると「Text」という項目があるので選択します。
※この項目はDetailsウィンドウの一番上にあるテキストボックスに入力した文字列が表示されます。
上記で追加することでTrackが追加されます。このトラックのタイムライン上に色や位置などを設定することでアニメーションを実装できます。
今回は文字をフェードインフェードアウトさせたいので透過度を設定する項目を追加します。
透過度は「Color and Opacity」で設定できます。
するとこのように各色と透明度を設定する項目が追加されます。
ここで「A」の項目を0に変更します。
この際、再生時刻を示すバーが0秒の位置にあることを確認してください。
次に再生時刻を0.75に移動させて今度は「A」の項目を1にします。
今度は1.5秒の位置に再生時刻を移動させて「A」の項目を同様に0へ変更します。
これで完成です!!
再生すると、フェードインフェードアウトされるアニメーションが確認できます!!
以降は透過どではなく、サイズを変更する場合について解説します。
操作はほとんど一緒なので不要な方は読み飛ばしてくださいね。
最初に追加した横棒を新たに追加して「Transform」を選択します。
たくさん項目が表示されるのでDeleteキーを押してScale以外を削除します。
ScaleのXを先ほどの透過度と同様に0秒のときには0、0.75秒のときには1、1.5秒の時に0とすると次のようにアニメーションさせることができます。
初級4:雨を降らせてみる(Niagara)
所要時間:5~10分
「Niagara System」アセットを作成する
まずはコンテンツブラウザ上で右クリックして「Niagara System」アセットを作ります。「Pick a starting point for your system」ウィンドウで「New system from selected emitter(s)」を選択します。
「Fountaion」と検索して右下の「+」ボタンでEmitterを追加します。
追加すると「Finish」が推せるようになるので押してアセットを作成します。
アセット名は「Rain」としました。
アセットを開くと次のような画面が出てきます。
「Rain」と書いてあるノードと「Fountain」と書かれているノードがあります。
「Rain」はこのアセット全体の処理に関して制御を行うノードになっており、1アセットにつき1ノードあります。
「Fountain」とはEmitterと呼ばれパーティクルの種類別に追加していきます。
例えば、「1.花火マテリアルと Niagara エミッタを作成する」で紹介されている花火(以下の画像)ではEmitterが4つ使われています。
所要時間:20~30分
しずくを作る
まず、「Fountain」にある「Add Velocity」を削除します。
初期状態ではこの項目でパーティクルを上方向に飛ばすように設定されています。
今回は重力に任せて落ちる雨をにします。
このように設定すると、一点からパーティクルが生成されて落ちていきます。
なので、発生地点を「shpere」から「Box / Plane」に変更します。
すると、少し幅をもって降らせることができます。
もう少し広い範囲で降らせたいので、「Box Size」を1000 x 1000にしてましょう。
(zは高さ方向なのでそのままがおすすめです)
範囲を広くするほど雨粒の生成がまばらになってしまっているので次はパーティクルのスポーンを増やしてみます。
パーティクルの数が増えるほど処理負荷に大きな影響を与えます。
「Spawn Rate」の項目にある「SpawnRate」を500に変更すると雨粒が増えます。
最後は雨粒っぽくパーティクルを棒状にしてみましょう。
「Initialize Particle」の「Sprite Attributes」→「Sprite Size Mode」を変更します。
これはどのようにサイズを決定するかを設定でき、今回は縦幅と横幅を別々で設定したいので、
「Random Non-Uniform」を設定します。
そして、各方向のサイズは画像のようにしました。
ここまでの設定をしてプレビューで見ると方向がばらばらになっているのがわかります。
これは回転もランダムな値になっているためです。
「Sprite Rotation Mode」を「Unset」に設定すると方向が一定になり雨を降らせることができました。
所要時間:30~60分
水のシミを作る
「しずくを作る」で作ったEmitterの「Particle Update」の「+」ボタンから「Collision」を追加します。
これによってパーティクルの衝突判定を実行できるようになります。
Collisionの項目を追加したことによって何かに衝突した瞬間にパーティクルが跳ね返るようになります。
※見やすさのため、パーティクルの形状を一時的に変更しています。
跳ね返らず消えてほしいので、先ほどと同じように今度は「Kill Particles」を追加します。
パーティクルが何かに衝突した瞬間にパーティクルの削除を行います。
次はパーティクルの削除を行うタイミングの設定を行います。
「Kill Particles」の項目の「Kill Particles」にある右側にある下向きの部分から選択し、「Show all」をクリックします。
次に「TRANSIENT CollisionValid」を選択します。このイベントは先ほどの「Collision」により衝突した瞬間に発行されるイベントです。
ここまで設定してLevel上に配置すると次のようになります。
※見やすさのため、パーティクルの形状を一時的に変更しています。
次に同じEmitterの「Particle Update」の「+」ボタンから「Generate Collision Event」を追加します。この項目でパーティクルが何かに衝突したときにイベントを発行します。このイベントをもとに水のシミを発生させます。
これを追加するとエラーが発生します。
パーティクルの区別をできないと位置情報などの情報が取得できないためエラーが発生します。
パーティクルの識別のためにIDを割り振ってもらうように設定します。
画像のように「Properties」の項目にある「Requires Persistent ID」にチェックを入れるとエラーが消えます。
ここからは水のシミを表現する「Emitter」を追加します。
右クリックで「Add Emitter」を選択して「Emitter」を新たに作成できます。
「sprite」と選択して「Simple Sprite Burst」という「Emitter」を追加します。
「Stage」というボタンを押して「Event Handler」を選択します。
「Event Handler」では別のエミッターの状態を受け取ったりすることができます。
次に上記で設定した雨粒の衝突を検出した際に発行されたイベントを対象に処理を行う設定をします。
「Event Handler Properties」を選択して受け取る「Collision Event」を選択します。
また、このイベントを受け取った際の処理のタイプを「Execution Mode」で設定します。
今回は雨粒が何かに衝突した際にパーティクルを発生させたいので「Spawned Particles」を選択します。
次にこのイベントを受け取った際にスポーンさせるパーティクル数の設定項目である「Spawn Number」を1に設定します。
次にイベントの発火を受け取る処理を追加します。
名前は直感的で「Receive Collision Event」を「Event Handler」から追加します。
ここまでで雨粒が何かに衝突した際にイベントを受け取り、パーティクルを新たに生成する設定ができました。
しかし、この状態では
最後に描画方法について設定を行います。
現在は雨粒同様にSpriteと呼ばれる描画方法になっています。
ここでは平面に対してシールのように描画したいので、「Decal」に変更します。
一旦「Render」のStageにある「Sprite Render」を削除します。
「Render」のStageから「Decal Renderer」を選択します。
しかし、デフォルトの設定では画像のような描画がされてしまうので、マテリアルをカスタマイズします。
「SphereMask」とは「B」を中心位置として「Radius」の範囲内に「A」の位置が入っているかを判定します。
「Hardness」は境界面に向かってグラデーションさせるかどうかを数値で設定できます。
「Light Vector」はDecal用の入力データで描画するDecalの範囲における位置情報が入力されます。
上記のマテリアルを「Decal Renderer」の「Material」に指定すると晴れて雨が当たった部分に染みを付けることができました!!
中級1:オブジェクトが破壊されたらディゾルブ表現でフェードアウトしてみる(Blueprint)
所要時間:5~10分
破壊オブジェクトを配置しマテリアルを設定する
単純に配置しただけでは次のように破片が残ったままになります。
Chaos Destructionで作成した「Geomerty Collection」には3つのマテリアルを設定することができます。
ここで重要となるのは上二つです。一つ目はメッシュ表面のマテリアルの設定項目となっており、2つ目は断面のマテリアルの設定項目となっています。
「マテリアルをいじってみる(Lumen、Blueprint)」で作ったマテリアルを二つ用意し、二種類の色を用意します。
このマテリアルを各項目に設定すると断面と表面で異なるマテリアルが設定できていることが確認できます。
所要時間:30~50分
破壊を検出してマテリアルのパラメータを更新する
「初級2:ものを砕いてみる(Chaos Destruction)」で作成したアセットをレベル上に配置します。
配置したアクタのBlueprintを実装するため該当のアクタを選択した状態で「+Add」の隣のボタンを押します。
以下のようなウィンドウが表示されますがそのまま「Select」を押してください。
すると、コンテンツブラウザ上に新たに「Blueprint Class」アセットが作成されます。
このBlueprintに破壊時の処理を実装していきます。
アセットを開くと上部に「Open Full Blueprint Editor」が表示されているのでクリックするとよく見るBlueprintのウィンドウが表示されます。
次にアクタが破壊された際に発火するイベントを設定します。
まず、ルートコンポーネントを選択し、Detailsウィンドウで「Event」と検索します。
検索で表示される「Notify Breaks」にチェックを入れます。
次に「On Chaos Break Event」の「+」からイベントを作成します。
このイベントを次のように実装します。
ここでの「BeginDestroyMaterial」は独自の関数です。
「BeginDestroyMaterial」関数の実装は次の通りです。
「CreateDynamicMaterialInstance」では「初級1:マテリアルをいじってみる(Lumen、Blueprint)」で作成したマテリアルを指定しています。
この関数では「DynamicMaterialInstance」というパラメータを変更するための特殊なマテリアルを作成し、「Fade」と「Speed」の二つを初期化してセットしています。
2つ分マテリアルを作成しているのは断面と表面の二つがあるためです。
このままではアニメーションがずっとループ再生されるため、Tick処理で一定時間過ぎたらアクタを破棄するようにします。
マテリアルのタイマーとBlueprintのタイマーの同期などでずれが発生する可能性があります。
回避する方法としてマテリアルのタイマーの値をBlueprintから設定してください。
別に間に合わなかったわけじゃ。。。
以下のようにタイマーで計測し、一定時間経過後アクタを破棄します。
無事実装出来ました!!
中級2:リスポーンする(Blueprint)
所要時間:5~10分
Blueprintで実装する
DestroyActorを呼ぶ前にSpawnActorで生成します。
SpawnActor後にBeginDestroyMaterialの「Fade」パラメータを1にしたバージョンの関数を呼び出すようにすればフェードインが実装できます。
※フェードイン時もループするので生成中のフラグを設定する必要はあります。
最後に
今回の記事を作るにあたって3回以上プロジェクトを作り直してかなり苦労しました。
もし僕がさらに進化させるなら次の実装をするかなっと思ってます。
- スポーン時にフェードインをする
- カウントダウンの実装
- タイムアウト時に入力を制限する(Enhanced Input)
難易度高めですが、ぜひ挑戦してみてください!!
Twitterでも質問やコメントお待ちしてます!!
今年の大仕事はこれでおわり!!
よい年末を!!