読者です 読者をやめる 読者になる 読者になる

妹でもわかるUnrealEngine4

毎日更新? 妹に説明するために書いてるけど、たまにわかってない場合もあるUnrealEngine4を中心としたゲーム制作の話。略すとイモリアル

毎日更新? 妹に説明するために書いてるけど、たまにわかってない場合もあるUnrealEngine4を中心としたゲーム制作の話。略すとイモリアル

ターン制ストラテジーゲームの中身をちょっとだけ見る

妹「ラーニングのターン制ストラテジーゲームってやつをやろうとしたんだけど、なんか人形が空中に浮いて変なことになってるんだけど……」

「それはUE4.9のバグみたいだね」

Turn Based Strategy bugged in 4.9 - UE4 AnswerHub

「ここで報告されてたから、4.9.1(仮)では直ってるはず」

妹「そうなのか。てっきりシューターゲームと同じで起動方法が悪かったのかと」

「でもこれも面白い作り方してあるね。レベル自体にはほとんど何にも置いてなくて、開始時にマップが自動生成されてる。典型的なBeginPlayで色々やってるやつだ」

妹「じゃあこれを研究してみる?」

「研究してもいいんだけど、妹が知らないアルゴリズムが出てくるんだよね。A*(エースター)アルゴリズムとか。指定したマスまで歩いていけるかどうかというのを調べるんだけど」

妹「それは必要なやつなのでは?」

「必要なんだけど、もう少しレベル上がってからの方がいい気がする。かなり大きなブループリントだったから。それにこれ根本的にゲームとして成立してない。よく見るとプロジェクトの説明にも」

ターン交代制のゲームの参考になる基本要素を含んでいます

「って書いてあるんだよね。だから操作方法がわからなくて調べないと遊べないというよりは、そもそも遊べない。ユニットを歩かせて向きを変えるぐらいしか出来ない」

妹「そうなのか。テンション下がってきた」

「だけどGameModeのブループリントをざっと眺めておくのはいいかもしれない。TBS_Gameという名前のブループリント」

f:id:una_unagi:20150910211940p:plain

「例えば一番最初に実行されるのがこの部分、現在のレベルにWorldData型のアクターがないか探して、見つかったらTBS_Game内の変数にセット、無かったらエラーメッセージを出してを中断するという仕組み。GameModeはどのレベルで使うかわからないから、レベルブループリントの時みたいにレベル上のアクタをドラッグしてノードを作れない。だからこういう手間のかかることをしてる」

妹「あれ? サンプルなのにWARNINGって出てない?」

「WorldData型の配列を作ってるのに、そこからWorldData型にキャストするのはおかしいからだね」

妹「なぜそんなおかしなことを?」

「もしWorldData型のアクタが1つもなかった場合、GetAllActorsOfClassの結果の配列が空だから、配列からデータをGETした結果がNoneになるんだよ。そうするとWorldData型へのキャストに失敗する」

妹「それでちゃんと動くなら、WARNINGの方が間違えてるの?」

「そういうことじゃなく、紛らわしいノードの組み方だから注意してる。全然動かないレベルのは黄色のWARNINGじゃなく赤のERRORになる。要はこれキャストするのが目的じゃなくて、アクタが見つからなかった時に分岐させるのが目的だから、別の書き方をすれば警告は出なくなる」

f:id:una_unagi:20150910213809p:plain

「例えばこんな感じ。見つからなかった場合は配列の長さが0になるから、配列に何か入ってる、長さが1以上になってる状態を条件にしたブランチノードに変えた。ぴったり1の時だけOKにしてもいいけど、一応元々の仕組みと同じ動作になるようにした」

妹「そういえばWorldDataが2つ以上あるとどうなるのこれ?」

「あんまり細かいことは考えずに、たまたま配列の0番に入ってた方を使ってる。もちろんUE4のシステム的に優先順位は決まってるんだろうけど」

妹「間違えて2つ作っちゃったのかもしれないし、やっぱり2つある時はエラーでいいのでは」

「そのへんはお好みで。こういう仕組みを作っておくと、レベルブループリントに書かなくても、各レベルごとに違うパラメータをGameModeに反映させることが出来るんだよ。今回のWorldData型場合はマスの大きさとか、部屋の大きさとかの数字パラメータだけしかないけど、アクターの参照を追加してもいい。この面のボスアクターはコレとか」

妹「でもこのサンプルの場合、そもそもレベルが1個しかないんだから、レベルブループリントに書けば良かったのでは……」

「そのへんは面を増やしたりなんだりで必要になるかもしれないし、GetGameModeノードでどのクラスからでもデータを参照しやすいという利点があるから、レベル1個でも使う意味はある。でも全部レベルブループリントで書いてあるサンプルもあるから、特に困ったことがなければそのままでもよさそう」