13
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unreal Engine (UE)Advent Calendar 2023

Day 25

UE5テンプレートプロジェクトから始めるゲーム開発

Last updated at Posted at 2023-12-24

はじめに

勉強で作っていた改造版サンプルプロジェクトの自慢をばと思い、初めての参加です。
また、各章にナンバリング振ってますが、何の意味もないです。
初級編に関しては独立しているので興味ある所だけやるのもよしです。

注意点

以降UnrealEngineのことをUEと書きます。
また、以下の基本的な操作ができることを前提としています。

  • サンプルプロジェクトを動かしたことがある
  • コンテンツブラウザ、レベル、アクタなどの基本用語がわかる
  • アクタの配置やBlueprintで音を鳴らすなどの単純なものであれば作れる
    • ただし、NiagaraやChaos Destructionなどはふわっと存在を知っていればOK

対象

何か作りたいけどアイデアない人
基本操作は覚えたけどそれ以上先に進めない人向けです。
全部サンプルプロジェクト内のアセットだけで完結させるので、お気軽に試してみてくださいね!!

最終結果

無題の動画 ‐ Clipchampで作成.gif

必要なもの

  • Unreal Engine 5

目次

  • 導入:サンプルプロジェクトを作る

パーツを作るフェーズ

  • 初級1:マテリアルをいじってみる(Lumen、Blueprint)
  • 初級2:ものを砕いてみる(Chaos Destruction)
  • 初級3:UIでアニメーション(Sequencer、UMG)
  • 初級4:雨を降らせてみる(Niagara)

組み込み例

  • 中級1:オブジェクトが破壊されたらディゾルブ表現でフェードアウトしてみる(Blueprint)
  • 中級2:リスポーンする(Blueprint)

ちなみに上級がないのは仕様です。
決して間に合わなかったわけでは。。。

導入:サンプルプロジェクトを作る

所要時間:5~10分

詳細 FirstPersonを好きなパスに作ってもらえれば完了です。

画像では「C++」を選択していますが、「Blueprint」でも問題ありません。

スクリーンショット 2023-11-08 121803.png

「最終結果」では明るさを下げてLumenの輝きを強調してます。

下の値を調整することで明るさを変更できますが、見づらくなるので以降では初期値を使用します。

レベル上のDirectionalLightを選択し、DetailsよりIntensityの項目を小さくすると暗くなります。

スクリーンショット 2023-11-14 125459.png

初級1:マテリアルをいじってみる(Lumen、Blueprint)

所要時間:5~10分

Lumenを設定する まず初めにプロジェクト設定からLumenが有効になっていることを確認します。 負荷が高い場合などはLumen以外を設定することで光源に関する処理が軽減される可能性があります。

スクリーンショット 2023-11-08 122404.png

コンテンツブラウザから右クリックでマテリアルを作成します。

スクリーンショット 2023-11-08 122436.png

マテリアルをダブルクリックするとBlueprintのような設定画面が表示されます。
右クリックをして「constant」と検索をかけて「Constant4Vector」を追加します。
画像のように既にあるEmissive Colorにノードをつなげると「Constant4Vector」のカラーが適用されます。
スクリーンショット 2023-11-08 122721.png

所要時間:20~30分

ディゾルブを実装する

無題の動画 ‐ Clipchampで作成.gif

新たに「DissolveMaterail」アセットを作ります。
スクリーンショット 2023-11-17 123930.png

次にResultノード(同名のマテリアル名にした場合は「DessolveMaterial」ノード)を選択した状態で詳細ウィンドウの「Blend Mode」を「Masked」にします。
スクリーンショット 2023-11-17 123803.png

次に「TextureSample」というノードを追加します。
スクリーンショット 2023-11-17 123626.png

詳細ウィンドウの「Texutre」に「T_Perlin_Nose_N」を追加します。
このテクスチャの模様でフェードアウトorフェードインします。
完成したらいろいろ試してみるとバリエーションが増えますね!!

スクリーンショット 2023-11-17 123712.png

※「noise」と検索しても出てこない場合

image.png

次にフェードインをするための時間を取得する関数を追加します。
「Time」と選択し、ノードを作り、詳細から「Period」にチェックを入れて「1.0」をセットします。
この値より大きな値になると0に値が戻ります。
image.png

最終形を先に載せますね。
スクリーンショット 2023-11-17 125236.png

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. 色を指定できるようにする。
  2. フェードイン&フェードアウトに対応する
  3. アニメーションの速度を変更可能にする

最終成果物は次の画像です。
image.png

1. アニメーションの速度を変更可能にする

外部に公開するパラメータは定数ノードを右クリックで「Convert to Parameter」とすると外部で設定できます。
スクリーンショット 2023-11-20 124401.png
色を設定するノードを上記のようにパラメータ化すると外部から設定できるようになります。

2. フェードイン&フェードアウトに対応する

「1-x」の箇所を変更します。
xは0から増加するので「x」を入力とすればよさそうです。
しかしマテリアルでif分を使うのはパフォーマンスの側面で避けるべきなので、
絶対値を使います。

スクリーンショット 2023-11-20 124137.png

一度、正しいか見てみましょう。
Fadeに0に設定すると「Substract」(引き算)で「0-x」となりその後絶対値を取るため「x」となり、フェードアウトになりますね。
逆にFadeに1を設定すると「1-x」の絶対値を取ることになり、フェードインになります。

3. アニメーションの速度を変更可能にする

時間を取得する関数に倍率を乗算するとできます。
注意として倍率がかかることで最大値が1ではなくなってしまうため、最小値を取るようにしています。

※最小値を取る理由
Aが1より小さい場合は1との最小値をとるとAが出力されます。
Aが1より大きい場合は1との最小値をとると1が出力されます。
一見直感的ではないですが、このように最大値を設定したい場合は最小値を計算すると良いです。

image.png

パラメータの設定方法

ブループリントで「Set Scalar Parameter Value on Materials」ノードにパラメータ名と値を指定します。
image.png

色の指定の場合はベクトルなので「Set Scalar Parameter Value on Materials」ノードを使って指定します。

初級2:ものを砕いてみる(Chaos Destruction)

所要時間:5~10分

対象となるオブジェクトを配置する はじめに破壊する対象のアクタをレベル上に配置します。

スクリーンショット 2023-11-08 122849.png

その後に「Select Mode」から「Fracture」を選択します。
スクリーンショット 2023-11-08 122927.png

ここで破壊の設定を行うために「New」を選択します。
スクリーンショット 2023-11-08 122952.png

すると、オブジェクトの破壊の設定をもつアセットを作ることができ、保存場所を聞かれます。
スクリーンショット 2023-11-08 123014.png

所要時間:10~20分

オブジェクトを分割する 今回の分割方法は均一に分割したいので「Uniforom」を選択します。

image.png

次に分割数を設定します。

分割数が増えるほど処理負荷に大きな影響を与えます。

「Uniform Voronoi」の項目にある「Min Voronoi Sites」を20、「Max Voronoi Sites」を100に設定します。

image.png

その後、最下部にある「Fracture」ボタンを選択すると分割がされます。

すると、Level上のアクタが分割されているのが分かります。

image.png

「Fracture」のウィンドウでの設定は異常なので「Selection Mode」に設定します。
image.png

このままPIEを起動すると以下のようにデバッグ用の表示がされた状態になります。
image.png

表示の設定は対象のアクタを選択し、詳細ウィンドウより「General」の項目にある「Show Bone Colors」のチェックを外せば切り替えることができます。

所要時間:20~30分

銃で破壊できるようにする 今のままでは銃で撃ったとしても破壊されません。 これは玉の衝突判定設定が原因となっています。

弾のアセットは以下に配置されています。

image.png

アセットを開き、衝突判定を担っている「CollisionComponent」を選択します。

image.png

詳細ウィンドウから「simulate Physics」にチェックを入れます。

image.png

それ以外にも衝突判定についてどのような挙動をするか設定する必要があります。

「Collision Enabled」を「Collision Enabled (Query and Physics)」に設定します。
image.png

次に弾が衝突した際には盛大に破壊したいので弾の質量を重く設定します。

image.png

また、壊れやすくしましょう。
「オブジェクトを分割する」で作ったアセットの詳細を開きます。
「damage」と検索し、「Damage Threshold」の0番目を「0.1」にします。
これによって壊れやすいオブジェクトになります。

image.png

※Damage Thresholdが複数ある理由
オブジェクトの分割を行った際に下部にある「Level」と紐づいています。
ダメージによって壊れ方を段階的に変えたい場合には複数回、分割をしてそれぞれ壊れやすさを設定することもできます。

image.png

初級3:UIでアニメーション(Sequencer、UMG)

無題の動画 ‐ Clipchampで作成.gif

所要時間:5~10分

「User Widget」アセットを作成する コンテンツブラウザから画像のように「Blueprint」を選択します。

image.png

選択すると「Pick Parent Class」ウィンドウが表示されます。
この項目はBlueprintで様々な機能を実装するにあたってベースとなる基盤を選択することができます。
今回は「User Widget」を選択します。

image.png

アセットを開くと次のような画面が表示されていれば成功です!!

image.png

所要時間:5~10分

文字を配置する まずは複数のパーツを配置できるようベースとなる「Canvas Panel」をドラッグ&ドロップで配置します。

image.png

正しく追加できていると左下の「Hierarchy」に「Canvas Panel」が追加されます!!

image.png

今回は文字を配置するために「Palette」で「Text」を検索してドラッグ&ドロップで追加します。

image.png

すると、テキストが配置されるだけではなく、星マークが付きます。
image.png

このマークは基準点となっており、この位置からの相対位置に文字が表示されます。
例えば、PCとipadなどウィンドウサイズが異なる場合に崩れなくなるので適切に設定することをお勧めします。

今回は中心に表示させるようにしてみましょう。
対象をクリックして「Anchors」から中心に配置しそうなものを選択します。

image.png

あとは相対位置を設定するだけです。
中央であれば相対位置を0にすればいいので「Position」を原点にします。

image.png

すると、左上に基準点が来てしまうので、「Alignment」でずらします。
テキストの範囲の中心を基準とするため0.5を設定します

image.png

※(x = 1、y = 0)にすると右上に来ます。

image.png

所要時間:5~10分

ゲームで表示させる 表示させるにはBlueprintで簡単な実装が必要です。 といっても二つだけです。 1. 対象のUserWidgetを生成する 2. 画面に配置する

まずは「Level Bluepirnt」を開きます。

image.png

「Construct」と調べて「Construct Object from Class」ノードを作ります。

image.png

「Class」に対象のクラス(『「User Widget」アセットを作成する』で作成したアセット名)を指定します。

image.png

今回はゲーム開始時から表示させたいので「BeginPlay」イベントに接続します。

image.png

image.png

次に表示をさせるために「Return Value」から「Add to Viewport」を選択します。

image.png

最終的に以下の画像のようになっていれば完成です!!

image.png

ゲームを開始するとカメラを移動させても中央に文字が表示されます。

image.png

無題の動画 ‐ Clipchampで作成 (1).gif

所要時間:20~30分

文字をフェードイン・フェードアウトさせる

文字が「Text Block」では味気ないので、Detailsウィンドウより「Content」→「Text」の文字を変更します。

image.png

すると表示される文字が変わります。
image.png

まずは、文字の下にあるラインを用意します。
「Palette」ウィンドウで「Image」を検索し画像のように配置します。

image.png

image.png

位置やアラインメントについては次の画像のように設定しました。
※Anchorは中央にしています。

image.png

ウィンドウの下部分にあるアニメーションウィンドウから「+Animation」を押して追加します。

image.png

右側のタイムライン上にある縦線が左から順にアニメーション開始時刻、再生時刻、アニメーション終了時刻です。
今回は1.5秒のアニメーションを実装するため一番右側の縦線を1.5の位置に移動させます。

image.png

次に文字を選択して「+Track」を選択します。

image.png

すると「Text」という項目があるので選択します。

image.png

※この項目はDetailsウィンドウの一番上にあるテキストボックスに入力した文字列が表示されます。

image.png

上記で追加することでTrackが追加されます。このトラックのタイムライン上に色や位置などを設定することでアニメーションを実装できます。

今回は文字をフェードインフェードアウトさせたいので透過度を設定する項目を追加します。
透過度は「Color and Opacity」で設定できます。

image.png

するとこのように各色と透明度を設定する項目が追加されます。

image.png

ここで「A」の項目を0に変更します。

この際、再生時刻を示すバーが0秒の位置にあることを確認してください。

次に再生時刻を0.75に移動させて今度は「A」の項目を1にします。

image.png

今度は1.5秒の位置に再生時刻を移動させて「A」の項目を同様に0へ変更します。
これで完成です!!

image.png

再生すると、フェードインフェードアウトされるアニメーションが確認できます!!
無題の動画 ‐ Clipchampで作成.gif

以降は透過どではなく、サイズを変更する場合について解説します。
操作はほとんど一緒なので不要な方は読み飛ばしてくださいね。

最初に追加した横棒を新たに追加して「Transform」を選択します。

image.png

たくさん項目が表示されるのでDeleteキーを押してScale以外を削除します。
image.png

ScaleのXを先ほどの透過度と同様に0秒のときには0、0.75秒のときには1、1.5秒の時に0とすると次のようにアニメーションさせることができます。

無題の動画 ‐ Clipchampで作成.gif

初級4:雨を降らせてみる(Niagara)

所要時間:5~10分

「Niagara System」アセットを作成する まずはコンテンツブラウザ上で右クリックして「Niagara System」アセットを作ります。

image.png

「Pick a starting point for your system」ウィンドウで「New system from selected emitter(s)」を選択します。

image.png

「Fountaion」と検索して右下の「+」ボタンでEmitterを追加します。
image.png

追加すると「Finish」が推せるようになるので押してアセットを作成します。
アセット名は「Rain」としました。

image.png

アセットを開くと次のような画面が出てきます。
「Rain」と書いてあるノードと「Fountain」と書かれているノードがあります。

image.png

「Rain」はこのアセット全体の処理に関して制御を行うノードになっており、1アセットにつき1ノードあります。
「Fountain」とはEmitterと呼ばれパーティクルの種類別に追加していきます。
例えば、「1.花火マテリアルと Niagara エミッタを作成する」で紹介されている花火(以下の画像)ではEmitterが4つ使われています。

image.png

所要時間:20~30分

しずくを作る

まず、「Fountain」にある「Add Velocity」を削除します。
初期状態ではこの項目でパーティクルを上方向に飛ばすように設定されています。
今回は重力に任せて落ちる雨をにします。
image.png

このように設定すると、一点からパーティクルが生成されて落ちていきます。
無題の動画 ‐ Clipchampで作成.gif

なので、発生地点を「shpere」から「Box / Plane」に変更します。

image.png

すると、少し幅をもって降らせることができます。

無題の動画 ‐ Clipchampで作成.gif

もう少し広い範囲で降らせたいので、「Box Size」を1000 x 1000にしてましょう。
(zは高さ方向なのでそのままがおすすめです)

image.png

範囲を広くするほど雨粒の生成がまばらになってしまっているので次はパーティクルのスポーンを増やしてみます。

パーティクルの数が増えるほど処理負荷に大きな影響を与えます。

「Spawn Rate」の項目にある「SpawnRate」を500に変更すると雨粒が増えます。

image.png

最後は雨粒っぽくパーティクルを棒状にしてみましょう。
「Initialize Particle」の「Sprite Attributes」→「Sprite Size Mode」を変更します。
これはどのようにサイズを決定するかを設定でき、今回は縦幅と横幅を別々で設定したいので、
「Random Non-Uniform」を設定します。
そして、各方向のサイズは画像のようにしました。

image.png

ここまでの設定をしてプレビューで見ると方向がばらばらになっているのがわかります。
これは回転もランダムな値になっているためです。

無題の動画 ‐ Clipchampで作成 (1).gif

「Sprite Rotation Mode」を「Unset」に設定すると方向が一定になり雨を降らせることができました。

image.png

所要時間:30~60分

水のシミを作る

「しずくを作る」で作ったEmitterの「Particle Update」の「+」ボタンから「Collision」を追加します。
これによってパーティクルの衝突判定を実行できるようになります。
image.png

Collisionの項目を追加したことによって何かに衝突した瞬間にパーティクルが跳ね返るようになります。

※見やすさのため、パーティクルの形状を一時的に変更しています。

無題の動画 ‐ Clipchampで作成.gif

跳ね返らず消えてほしいので、先ほどと同じように今度は「Kill Particles」を追加します。
パーティクルが何かに衝突した瞬間にパーティクルの削除を行います。
image.png

次はパーティクルの削除を行うタイミングの設定を行います。
「Kill Particles」の項目の「Kill Particles」にある右側にある下向きの部分から選択し、「Show all」をクリックします。
次に「TRANSIENT CollisionValid」を選択します。このイベントは先ほどの「Collision」により衝突した瞬間に発行されるイベントです。
image.png

このように表示されれば完成です。
image.png

ここまで設定してLevel上に配置すると次のようになります。

※見やすさのため、パーティクルの形状を一時的に変更しています。

無題の動画 ‐ Clipchampで作成 (1).gif

次に同じEmitterの「Particle Update」の「+」ボタンから「Generate Collision Event」を追加します。この項目でパーティクルが何かに衝突したときにイベントを発行します。このイベントをもとに水のシミを発生させます。
image.png

これを追加するとエラーが発生します。
パーティクルの区別をできないと位置情報などの情報が取得できないためエラーが発生します。
image.png

パーティクルの識別のためにIDを割り振ってもらうように設定します。
画像のように「Properties」の項目にある「Requires Persistent ID」にチェックを入れるとエラーが消えます。
image.png

ここからは水のシミを表現する「Emitter」を追加します。
右クリックで「Add Emitter」を選択して「Emitter」を新たに作成できます。
image.png

「sprite」と選択して「Simple Sprite Burst」という「Emitter」を追加します。
image.png

「Stage」というボタンを押して「Event Handler」を選択します。
「Event Handler」では別のエミッターの状態を受け取ったりすることができます。
image.png

次に上記で設定した雨粒の衝突を検出した際に発行されたイベントを対象に処理を行う設定をします。
「Event Handler Properties」を選択して受け取る「Collision Event」を選択します。

image.png

また、このイベントを受け取った際の処理のタイプを「Execution Mode」で設定します。
今回は雨粒が何かに衝突した際にパーティクルを発生させたいので「Spawned Particles」を選択します。
image.png

次にこのイベントを受け取った際にスポーンさせるパーティクル数の設定項目である「Spawn Number」を1に設定します。
image.png

次にイベントの発火を受け取る処理を追加します。
名前は直感的で「Receive Collision Event」を「Event Handler」から追加します。

image.png

ここまでで雨粒が何かに衝突した際にイベントを受け取り、パーティクルを新たに生成する設定ができました。
しかし、この状態では

最後に描画方法について設定を行います。
現在は雨粒同様にSpriteと呼ばれる描画方法になっています。

ここでは平面に対してシールのように描画したいので、「Decal」に変更します。
一旦「Render」のStageにある「Sprite Render」を削除します。

image.png

「Render」のStageから「Decal Renderer」を選択します。
image.png

しかし、デフォルトの設定では画像のような描画がされてしまうので、マテリアルをカスタマイズします。
image.png

まずは空のマテリアルを作成します。
image.png

画像のようにマテリアルを実装します。
image.png

「SphereMask」とは「B」を中心位置として「Radius」の範囲内に「A」の位置が入っているかを判定します。
「Hardness」は境界面に向かってグラデーションさせるかどうかを数値で設定できます。

■「Hardness」が0の場合
image.png

■「Hardness」が100の場合
image.png

「Light Vector」はDecal用の入力データで描画するDecalの範囲における位置情報が入力されます。

上記のマテリアルを「Decal Renderer」の「Material」に指定すると晴れて雨が当たった部分に染みを付けることができました!!
image.png

中級1:オブジェクトが破壊されたらディゾルブ表現でフェードアウトしてみる(Blueprint)

所要時間:5~10分

破壊オブジェクトを配置しマテリアルを設定する

単純に配置しただけでは次のように破片が残ったままになります。

無題の動画 ‐ Clipchampで作成 (2).gif

Chaos Destructionで作成した「Geomerty Collection」には3つのマテリアルを設定することができます。

image.png

ここで重要となるのは上二つです。一つ目はメッシュ表面のマテリアルの設定項目となっており、2つ目は断面のマテリアルの設定項目となっています。

「マテリアルをいじってみる(Lumen、Blueprint)」で作ったマテリアルを二つ用意し、二種類の色を用意します。

image.png

このマテリアルを各項目に設定すると断面と表面で異なるマテリアルが設定できていることが確認できます。

無題の動画 ‐ Clipchampで作成.gif

所要時間:30~50分

破壊を検出してマテリアルのパラメータを更新する

「初級2:ものを砕いてみる(Chaos Destruction)」で作成したアセットをレベル上に配置します。

image.png

配置したアクタのBlueprintを実装するため該当のアクタを選択した状態で「+Add」の隣のボタンを押します。

image.png

以下のようなウィンドウが表示されますがそのまま「Select」を押してください。

image.png

すると、コンテンツブラウザ上に新たに「Blueprint Class」アセットが作成されます。
このBlueprintに破壊時の処理を実装していきます。

image.png

アセットを開くと上部に「Open Full Blueprint Editor」が表示されているのでクリックするとよく見るBlueprintのウィンドウが表示されます。

image.png

次にアクタが破壊された際に発火するイベントを設定します。
まず、ルートコンポーネントを選択し、Detailsウィンドウで「Event」と検索します。

image.png

検索で表示される「Notify Breaks」にチェックを入れます。

image.png

次に「On Chaos Break Event」の「+」からイベントを作成します。

image.png

image.png

このイベントを次のように実装します。
ここでの「BeginDestroyMaterial」は独自の関数です。

image.png

「BeginDestroyMaterial」関数の実装は次の通りです。

image.png

「CreateDynamicMaterialInstance」では「初級1:マテリアルをいじってみる(Lumen、Blueprint)」で作成したマテリアルを指定しています。
この関数では「DynamicMaterialInstance」というパラメータを変更するための特殊なマテリアルを作成し、「Fade」と「Speed」の二つを初期化してセットしています。

2つ分マテリアルを作成しているのは断面と表面の二つがあるためです。

このままではアニメーションがずっとループ再生されるため、Tick処理で一定時間過ぎたらアクタを破棄するようにします。

マテリアルのタイマーとBlueprintのタイマーの同期などでずれが発生する可能性があります。
回避する方法としてマテリアルのタイマーの値をBlueprintから設定してください。
別に間に合わなかったわけじゃ。。。

無題の動画 ‐ Clipchampで作成 (2).gif

以下のようにタイマーで計測し、一定時間経過後アクタを破棄します。

image.png

無事実装出来ました!!

無題の動画 ‐ Clipchampで作成.gif

中級2:リスポーンする(Blueprint)

所要時間:5~10分

Blueprintで実装する

DestroyActorを呼ぶ前にSpawnActorで生成します。

image.png

SpawnActor後にBeginDestroyMaterialの「Fade」パラメータを1にしたバージョンの関数を呼び出すようにすればフェードインが実装できます。
※フェードイン時もループするので生成中のフラグを設定する必要はあります。

最後に

今回の記事を作るにあたって3回以上プロジェクトを作り直してかなり苦労しました。
もし僕がさらに進化させるなら次の実装をするかなっと思ってます。

  • スポーン時にフェードインをする
  • カウントダウンの実装
  • タイムアウト時に入力を制限する(Enhanced Input)

難易度高めですが、ぜひ挑戦してみてください!!
Twitterでも質問やコメントお待ちしてます!!

今年の大仕事はこれでおわり!!
よい年末を!!

13
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?