UE4初心者が第5回UE4ぷちコンにノベルゲーム等の作品を作って応募しました。
※イベントBeginPlayの挙動をぷちコンで初めて理解するほどのド素人です。
ぷちコン応募作品
そんな初心者が、なんの熱意が生まれたのか第5回UE4ぷちコンを3作品作りました。
【第5回UE4ぷちコン応募作品】 ユニティちゃんのハート集め
https://www.youtube.com/embed/d0232-UcHvo
【第5回UE4ぷちコン応募作品】こはくちゃんズでわかるUE4ぷちコン 愛のチュートリアル
https://www.youtube.com/embed/HlORm-ei5Do
【第5回UE4ぷちコン応募作品】愛、見つめていますか?
https://www.youtube.com/embed/4Al2XfehVOo
ぷちコン作品を開発して、少しだけUE4に詳しくなりました。
UE4でノベルゲーム作り
この中でも自分が特に熱意をもって挑戦したのは、UE4でノベルゲームは作れるのだろうかというところです。
その結果が「こはくちゃんズでわかるUE4ぷちコン 愛のチュートリアル」です。
割とノベルゲームっぽくできたと思います。
UE4の初心者がどうやってノベルゲーム作ったのかを書いていきたいと思います。
参考にしたサイト等
以下のサイトを参考にさせていただきました。
ちょこっとアンリアル(Enjoy2Unreal)ノベルゲームをつくってみる その1~その5
シナリオデータについて紙パレット コミティアT37a様のTwitterで公開したシナリオのデータテーブルが非常にわかりやすかったので、構造のみそのまま引用させていただきました。
会話ダイヤログですがBlueprint Dialogueを参考に自分に使いやすいように作り直しました・・!。データーテーブルで会話をセットアップ出来るようにしてあります。もっと最適化できそうだけどとりあえず動きました・・。#UE4 pic.twitter.com/Vfas9uWA2s
— 紙パレット コミティアT37a (@kamipallet) 2016年4月9日
素材は
キャラクター:ユニティちゃんのADV素材
背景画像:背景写真補完の会
UI素材:びたちー素材館
を利用させていただきました。
ノベルゲーム作り
## 構造体&データテーブル
シナリオはCSVに書き込んだため、構造体を用いてデータテーブルを作成しました。
## 背景画像、立ち絵表示
背景画像、立ち絵はPaperSpriteActorで表示しています。
立ち絵は画像を入れ替えたいため、NovelCharacterBluprintというBPを作成して動的に切り替えるようにしました。
GameMode & PlayerController
マウスの左ボタンをクリックして文章を進めるため、PlayerContorollerを継承したBPを作成します。
![controller.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2Fd32ffedf-0e91-1f44-a730-32d75b38f44b.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=9157d024f64d9827fa10dd2f9c613bcb)
名前はNovelPlayerControllerと名づけています。
このNovelPlayerControllerをGameModeに反映させるため、NovelGameModeというBPを作成して設定しています。
![中身.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2Fa854b080-e255-3274-2ade-c24e17afec54.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=9704361554521eb5a09f1af4b0af3759)
NovelGameModeを設定→プロジェクト設定のマップ&モードで設定しています
![プロジェクト設定.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2F80a8ce7c-0567-ba09-5785-2909b17876a7.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=89de41d6be2942b1facf6a7b77a1e1ce)
NovelPlayerController
シナリオデータ読み込み、マウスのクリック処理はNovelPlayerControllerに記載しました。
BPの詳細内容です。
イベントグラフ
マウス入力を受け付けるため、BeginPlayからEnableInputを呼び出し、GetDataTableRowNamesでシナリオデータを読み込み、ForEachLoopでまわしてデータをセットしています。
かなり汚いです。もっと効率のいいやりかたがありそうな気がします。
マウスを左クリックしたときに、次に表示するメッセージを取得します。
最後にシナリオデータに書かれたコマンドを判定します。
今回はEndというコマンド名が来たら、タイトルをOpenLevelで開く処理のみ実装しています。
立ち絵表示(showCharacter)
この関数が呼ばれたら、立ち絵画像をすべて薄い黒色に表示した後、会話をするキャラクターの立ち絵をシナリオデータを参照して表示します。
時間がなかったとはいえ、キャラクターの名前で表示する画像のリストを判定を入れているのはバッドノウハウです。
もっといい方法が間違いなくあると思うので、上記は参考程度にしてください。
NovelCharacterBlueprint
立ち絵のクラスです。Actorクラスを継承しています。
ビューポート
![NovelCharacterBlueprint.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2Fed2df0b9-7f39-0d53-876d-1250516626ff.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=037451df748ea7943d579b418d1cc29f)
Actorクラスの子にPaperSpriteが入っています。
PaperSpriteを継承しなかったのはとある理由があります。
立ち絵変更(SetCharacterImage)
![SetCharacterImage.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2Fa5e1f1bb-59c0-0fe3-54ff-bbc383fdd550.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=266766f7c299d376ef2dab6c62322c51)
立ち絵(Sprite)を切り替える関数です。
PaperSpriteを継承したときはSetSpriteを呼んでもSpriteが切り替えられませんでした。
Actorの子にした場合はSetSpriteで切り替えられたため、そういう仕様っぽいです。
ブラックアウト(CharacterBrackOut)
![CharacterBrackOut.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2Ffc24b33c-05f5-054a-99a5-17f5fdcab855.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=3349156c93900877e435d130f68ad7c8)
下記の画像の通り、会話をしていないキャラクターを少し暗くするための関数です。
外部のクラスから呼ばれることを想定しています。
UI(NovelUI)
テキストを表示するためのUIを作成します。
デザイナー
![デザイン.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2F2d1f80b9-2496-e361-0914-02e6c0c2fd71.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=69bef7c89bcf358c632bd32533459ffc)
デザインはこの通りです。
選択肢のボタン3つと、キャラクター名表示、本文表示を設置しています。
グラフ
選択肢ボタンのクリックイベントグラフ、テキストと選択肢ボタンを表示するために沢山のバインドクラスを作成しました。
####イベントグラフ
![イベントグラフ.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2Fd8ecc2b0-3519-73fe-2ff9-d05a60ee5ca4.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=39883b99d4c943549a6785aa3807885d)
選択肢ボタンのクリックイベントを拾っています。
押した場合、該当のシナリオにジャンプする処理です。
####バインドクラス
テキストを表示、選択肢ボタンの表示およびラベル表示をバインドクラスに設定しています。
・本文表示
![メッセージ表示.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2F9483d855-15ee-ab5b-8ea8-043f7becd9c7.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=52af71799e38121dd837e0084792b2af)
データテーブルでは改行コードは文字列(\nなど)に変換されるため、Replaceで改行コードに変換をかけます。
ToにShift+Enterで改行が入力できます。
Replaceをはさむことで上記の画像のようにちゃんと改行表示ができます。
GetSubstringの部分で流れるような文字列表示をしています。
ただ、UIではDelayが使用できないため、文字表示のスピードを変更したい場合はHUDで作成するか、別のBPに処理を書いたほうがよさそうです。
・キャラクター名表示
キャラクター名を表示するバインドクラスです。
・選択肢表示
![選択肢ボタン表示.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2F525e1a73-aa1b-6812-3ca6-2411e264eb73.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=633abcd307dc9133cc004eea7712fe39)
![選択肢ボタンラベル表示.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2Fec40b0b8-7f11-42dd-6013-16bcdccc3ea7.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=4694abd21e4d5ae14050b8dbe7fafd6e)
データテーブルで選択肢のラベルがあった場合、以下の画像のようにボタンとボタンラベルを表示するバインドクラスです。
・シナリオジャンプ処理
![シナリオジャンプ.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2F19d8b482-1a2a-c0ea-47f8-3c2223d3c7c8.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=82b5c1b0d8ce7707bd823302707bb0cc)
シナリオにジャンプする関数です。
選択肢を選んだ場合、該当のシナリオに本文のインデックスを設定するためのクラスです。
以下のローカル変数をセットしています。
![シナリオジャンプ.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2F610cc092-e7d2-fd34-b634-2b4766508625.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=79e22d7acb97d47bc72110399fbe3fff)
レベルブループリント
レベルブループリントはUIの表示とアウトライナに格納したNovelCharacterBlueprintをNovelPlayerController.CharacterArrayに入れる処理を行っています。
![level.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F104377%2Fa9aa76f7-f18a-575b-4f9e-675a8af3f2f5.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=a86551a7d0254e014fb89ccadf2b4c83)
まとめ
UE4でも割と簡単にノベルゲームは作れます。
初心者ですらADVのエンジンっぽいものが作れる当たり、UE4は素晴らしいゲームエンジンです。
せっかく簡易的とはいえノベルゲームのエンジンを作ったので、UE4の勉強のためにもバックログなどノベルゲームでは当たり前に実装されている機能を追加していきたいと思っています。
© Unity Technologies Japan/UCL
©びたちー素材館
©背景写真補完の会