
マイケル
みなさんこんにちは!
マイケルです!

エレキベア
こんにちクマ〜〜〜

マイケル
「ミニゲームの制作過程を通してUnrealC++で開発する際の方法をざっくり知ろう」という趣旨で、全三回に分けてUnrealEngineでのミニゲーム制作について紹介しています。
前回はキャラクター制御とゲーム内容の実装について紹介したので、今回は仕上げとして味付けを行います!

【UE5】第一回 ミニゲーム制作で学ぶUnrealC++ 〜UnrealC++の概要 編〜
2024-05-18

【UE5】第二回 ミニゲーム制作で学ぶUnrealC++ 〜キャラクター・ゲーム実装 編〜
2024-05-18
▲前回の記事
▲制作したゲーム

エレキベア
猫のランゲームについて制作したのだったクマね

マイケル
今回は仕上げとして
・UIの実装
・タイトル画面の作成とレベル遷移
・サウンド、エフェクト実装
について紹介していきます。
コードは下記リポジトリにあげていますので、こちらもよければ合わせてご参照ください!
▼GitHubリポジトリ
GitHub - plasmo310 / ue5-cat-runner
▼UnrealEngineバージョン
5.3.2

エレキベア
やったるクマ〜〜〜
参考書籍

マイケル
今回実装・情報整理するにあたり、下記書籍を参考にさせていただきました!

C++でつくるUnreal Engineアプリ開発 for Windows & ...

Unreal Engine 5で極めるゲーム開発:サンプルデータと動画で学ぶゲー...

マイケル
C++でつくるUnreal Engineアプリ開発は、UE4の情報にはなりますが数少ないC++について触れられた書籍です。
Unreal Engine 5で極めるゲーム開発は通称極め本と呼ばれていて、業界内では定番書籍として扱われています。
量はありますが、一度見ておいて損はないと思います!

エレキベア
極め本はUE4版もあったクマが、UE5になってまたボリュームが大きくなったクマね
UI制御の実装

マイケル
まずはUIの実装から見ていきます。
UE5ではUMG (Unreal Motion Graphics) という機能を使用して実装します。
UMGの概要について

マイケル
UMGはUnityでいうところのCanvas的なイメージで、Widgetという単位で作成します。
Widgetの中に更にWidgetを入れ子構造で持たせることもできるので、制御しやすい単位でWidgetを分けるのが重要になります。
参考:
UnrealEngineドキュメント - UMG UI デザイナのクイック スタート ガイド
UnrealEngineドキュメント - UMG UI デザイナ ユーザーガイド

▲UnityでいうCanvas的なイメージ

▲Widget内にWidgetを入れ子にできる

マイケル
ちなみに今回は下記のような単位で作成しています。
Widgetとして分けておくと、ある程度まとめての表示/非表示切り替えの制御も行いやすいです。
Widgetの分割単位
Widget名 | 役割 |
---|---|
RunGameWidget | 以下のWidgetを含む |
RunGameScoreInfoWidget | スコア情報 |
RunGameMessageInfoWidget | メッセージ表示 |
RunGameLevelUpWidget | レベルアップ表示 |
RunGameResultWidget | リザルト表示 |

エレキベア
UMGではWidgetの単位で考えるクマね

マイケル
あとはUMG画面内でアニメーションが作成できたり、Imageの角を丸められたりなどといった機能も付いているのが便利です。

▲UMG内にアニメーションタブもある

▲ProceduralUIのような機能も付いている

エレキベア
角を丸められるのはUnityだと有料アセットでしか見ないクマからこれはありがたいクマね

【Unity】「Procedural UI Image」を使ってシンプルなUIを爆速で作成する
2022-08-22
▲UnityではProcedural UI Image という有料アセットで似たようなことができる

マイケル
予想ではあるけど多分Unrealの機能であったからUnityでも使えるようにしたのかな?と思っています。
Unityでも標準機能にしてほしい・・・。
UI表示の動的操作について

マイケル
そしてコードからUIをどう操作するのか?についてですが、まずUUSerWidgetクラスを継承したクラスを親クラスに指定してWidgetを作成する必要があります。
▲UUSerWidgetを継承して作成する

▲Widget作成時に親クラスとして指定する

マイケル
そして個々のUI要素を紐づける方法はいくつかありますが、今回はUPROPERTYにメタ属性として「BindWidget」「BindWidgetAnim」を指定することで紐づける方法を使用しています。
こうすることで、コンパイル時に変数名と同名のUI要素を紐づけてくれます。
▲UPROPERTYでBindWidgetを設定することで紐づける

エレキベア
自動バインディング的な機能があるのクマね

マイケル
ちなみにコンパイル時にエラーにしたくない場合には「BindWidgetOptional」など後ろに「Optional」と付けることで回避できます。
またコードを使用しないプロパティバインディングについては、下記の公式ドキュメントをご参照ください。
参考:
UnrealEngineドキュメント - プロパティのバインディング

エレキベア
絶対にUIと紐づけられてるのを保証するのであれば、Optionalは付けない方がよさそうクマね
その他Tips
まとめて操作したい場合にはBorder等でまとめる

マイケル
アニメーション等で複数のUI要素を一括で操作したい場合、Border等でまとめると解決する場合があります。

▲一括で操作したい場合、Border等でまとめる

エレキベア
ちょっと面倒くさいクマね・・・
画面解像度に合わせてUI要素をスケーリングする設定

マイケル
また、Unityのように画面解像度に合わせてUI要素をスケーリングしたい場合、
caleBox、SizeBox、CanvasPanelの順で格納するといい感じに調整できました。

▲画面解像度に合わせてスケーリングする場合
参考:
ウィジェットの大きさを画面に合わせる その2 - 妹でもわかるUnrealEngine4

エレキベア
これで画面解像度が変わっても比率を守って調整してくれるクマね

マイケル
お手軽で調整できますが、パフォーマンス面を考慮する場合には他の方法を検討する必要もあるかもしれません。
レベル遷移の実装

マイケル
次にレベル遷移処理を把握しておきたかったこともあり、簡易的なタイトル画面を作成してみました。
こちらを使用してレベル遷移を実装してみます。

▲とりあえず作成したタイトル画面
レベル遷移処理

マイケル
とはいえレベル遷移させるの自体は簡単で、用意されているUGameplayStatics::OpenLevel関数を呼び出すだけで遷移することができます。
▲レベル遷移処理

エレキベア
まあこんなもんクマね
GameInstanceを使用したデータ保持

マイケル
課題となるのはこのレベル間でデータを共有するのをどうするか?になります。
こちらはレベル遷移しても保持されるGameInstanceクラスを生成してプロパティを保持することで対処しました。
参考:
Qiita - UE4 GameInstance、Singletonへc++からアクセスする
UnrealEngineドキュメント - ゲーム フローの概要

マイケル
今回の規模だと基本的に保持するデータはないのですが、オーディオ再生を管理するクラス(AudioService)のみ保持することにしました。
注意点として、UPROPERTYを付与しておかないとGC対象となってしまうことがあることです。
自分はこれのせいでMacだけデータが保持されずしばらく調査に悩むといった事象にあたりました...。

エレキベア
UPROPERTYの付け忘れは恐ろしいクマ・・・
サウンド・エフェクトの実装

マイケル
最後に味付けでサウンドとエフェクトを実装します。
サウンド再生の実装

マイケル
サウンド再生もそこまで難しいことはなく、音源をUSoundBaseクラスとして取得し、UGameplayStatics::PlaySoundXXX関数を使用することで再生できます。
▲基本の2D/3D再生

エレキベア
位置も渡すことで3D再生できるのクマね

マイケル
もう一つの方法として、UAudioComponentを作成して操作する方法があります。
こちらはUnityでいうAudioSource的なもので、再生・停止といった操作も柔軟に行うことができます。
▲AudioComponentの定義
▲AudioComponentによる再生

マイケル
今回はこのような簡潔な処理をAudioServiceクラスとして抜き出して作成しています。
ボリューム調整など、サウンド周りはもう少し作り込む余地がありそうですね。

エレキベア
Unityで頑張って実装したオーディオクラスは下記を参照してくれクマ〜〜

【Unity】サウンドミドルウェアに依存しない設計を考える【CRI ADX・Wwise】
2024-03-27
エフェクト再生の実装

マイケル
エフェクト再生については、Niagaraという機能を使用して作成しています。
こちらはUnityでいうShurikenのようなもので、高機能なパーティクルシステムとなっています。
UnrealEngineドキュメント - Niagara のクイックスタートガイド

エレキベア
Niagaraという名前はよく聞くクマ

マイケル
GPUSimulationという機能を使用してComputeShaderの代わりにも使えたりと、中々奥が深い機能なんだ。
こちらも別途別の記事で紹介しようかなと思っています!
Niagaraの構成要素
エフェクトの構成

マイケル
Niagaraは大きく「システム」「エミッタ」で構成されています。
システムはレベルに配置できる単位で、その中に放出源であるエミッタを複数持たせることができます。

- システム
- レベルに配置することのできる単位
- エミッタを複数持つことができる
- エミッタ
- パーティクルの放出源
- 他のシステムからも使用することができる
エミッタの構成

マイケル
そしてエミッタはモジュールという機能を持たせることで実装します。
数や放出する形状、速度などを設定した後、レンダラーにスプライトやメッシュ等を指定することで描画することができます。

- モジュール
- 上から下に向かうように1つずつ順番に実行され、更新モジュールは毎フレーム繰り返し実行される
- エミッタのスポーン、更新など、ラックの一つ一つがモジュールに該当する
- レンダラー
- 処理した粒子の位置等の情報を拾い、実際に画面に表示させる
- スプライト、メッシュなどの種類がある

エレキベア
大体イメージは分かったクマ
モジュールについてはまたいろいろ勉強する必要はありそうクマね
星のエフェクト

マイケル
今回は星のテクスチャを使ったエフェクトを複数用意していて、打ち出す数と形状を変えることで印象を変化させています。

▲アイテム取得時などのエフェクト


▲一つを真上に打ち出す

▲三つを真上にCone状で打ち出す

▲多量を球状に打ち出す

エレキベア
同じテクスチャでもモジュールを変えることでいろんなエフェクトが作れるのクマね
煙のエフェクト

マイケル
そしてプレイヤー死亡時の煙(爆発?)は、下記のようなもわっとしたテクスチャを用意して球状に打ち出すことで表現しました。


▲煙を球状に打ち出す

エレキベア
簡単なエフェクトクマね

マイケル
作成したエフェクトは以上になります!
今回実装したのは本当に簡単なものだけど、作り込めば商用レベルのエフェクトを作ることも可能なので、興味がある方はいろいろ試してみてください!
おわりに

マイケル
以上でゲームは完成です!
三回分に分けて紹介してみましたが、どうだったかな?

エレキベア
やっぱゲーム制作は楽しいクマ〜〜〜
こういう小規模なゲームでも一通り作ると開発の感触が掴みやすいクマね

マイケル
UnrealEngineだとどうしても大規模なゲーム開発がメインになるから、ミニゲーム規模で理解しやすいプロジェクトが中々ないんだよね・・・
今回の記事が誰かの役に立てば幸いです!

エレキベア
まあ個人開発規模のゲームなら正直Unityの方が向いてそうクマからね・・・

マイケル
今後はもちろんUnityも触っていきますが、UnrealEngine関連の記事も増えるかもしれないのでお楽しみに!
アデューー!!

エレキベア
おつかれクマ〜〜〜〜
【UE5】第三回 ミニゲーム制作で学ぶUnrealC++ 〜UI・仕上げ実装 編〜 〜完〜

【UE5】第一回 ミニゲーム制作で学ぶUnrealC++ 〜UnrealC++の概要 編〜
2024-05-18

【UE5】第二回 ミニゲーム制作で学ぶUnrealC++ 〜キャラクター・ゲーム実装 編〜
2024-05-18

【UE5】第三回 ミニゲーム制作で学ぶUnrealC++ 〜UI・仕上げ実装 編〜
2024-05-18