企画記事
【完全ガイド】制作経験ゼロの社会人向けゲーム制作入門。夏休みを使って,Unreal EngineのFPSミニゲームを完成させてみよう
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
10 | メイン処理 | スコアをカウントしよう | P.5(10)へ |
10.スコアをカウントしよう
メイン処理 2/2
レベルと「的」が作れるようになった。これで,簡単な射撃演習場に仕上げることもできる。
「そういえば,あのゲームはどんな感じに配置されてたっけ」と好きなゲームを起動して,それを参考にしながら,自分なりに作ってみても楽しいだろう。
さて話は戻るが,本記事で目標としているのは「ミニゲーム」の完成だ。ミニゲームっぽくしていくために,ゲームルールを実装していこう。
今回はレベル上の「的」を,すべて撃ち落とせばゲームクリアとする。制限時間やゲームオーバーはなしだ。
実装の流れとしては,「スコアを加算していく仕組み」を作成し,「的」が撃たれたときに実行する処理を実装する。
具体的には,スコアを加算していく「AddScore」というイベントを自作し,「的」の「On Component Hit(Cube)イベント」で「AddScoreイベント」を呼び出す流れだ。
この仕組みを作り,少しずつ機能を広げながら,ゲームクリアまでを実装していこう。
Custom Event ノード | ||
自由にカスタマイズできるイベント 自動的にトリガーされる仕組みが備わっていないので,作っただけでは動かない しかるべきタイミングで呼び出して,動かそう |
さて,今作った「AddScoreイベント」の中身,つまり「スコアを加算する処理」を実装していこう。
スコアを加算していくには,現在のスコアを記憶しておく仕組みが必要だ。現在のスコアを忘れてしまった状態で,「的」を撃ってスコアが1増えたとしても,結局いくつなのかが分からなくなる。
現在のスコアを紙に書いておけば,そんな問題とはおさらばだ。紙に書いておくように,値を保存しておく「変数」というものを利用する。
今回は「Score」という変数を用意して,「的」を撃ちぬいた数をカウントしていこう。
まず,「変数」とは値を保存するための「箱」のようなものだ。この箱に保存された値を参照したり書き換えたりしていくことで,得点の管理やスコアボードの作成,プレイヤーネームの表示などさまざまなことができる。
そして,「変数」には「型」というものがある。整数,小数などの数値や,文字列,オブジェクトなど,さまざまなデータの形式を表し,目的に合わせて使い分ける。
今回作成するゲームは,「的」を落とした数を,そのままスコアとする。何かの個数を数える時は,1,2,3……と整数(数学的には自然数だが……)を用いるので,「Score変数」の「型」は「Integer」(整数)を選択した。
変数 | 値を保存しておくための箱 |
型 | 変数の形式(種類) |
整数を表現できる「型」は「Integer」のほかにも「Byte」や「Integer 64」などが用意されているのだが,どちらも癖があるので,基本的に整数を扱う場合は「Integer」と覚えて大丈夫だ。
座学で覚えようとすると,大変かもしれない。ブループリントでは「型」ごとに色が設定されているので,色を頼りに作業していたら,自然と感覚が掴めていることだろう。詳細を覚えていくのは,その後からでも全然構わないのだ。
数字でも「整数」や「小数を含む数」など,「型」が細かく分けられているのには,いくつか理由がある。その1つがリソースの削減だ。
これは,ダンボールをイメージしてくれればよい。荷物を発送する際に,大きなダンボールがあればどんな荷物が来ても中に入れられるが,場合によっては無駄なスペースが大きくなる。変数も同じで,範囲が広いものを常に使用しているとリソースを食い荒らし,PCに余分な負荷をかけてしまうのだ。
また,もう1つの理由として,意図しないデータのやり取りを防ぐことが挙げられる。
例えば,WEBでフォームに入力する際,電話番号や郵便番号の入力で「全角数字」を入力したら「半角数字で入力してください」または,その逆で「半角数字」を入力して「全角数字で入力してください」と,怒られた経験はないだろうか。これは,入力できるデータ形式を制限することで,プログラマが想定していないデータの入力を防いでいるのだ。
Increment Intノード | ||
「Integer型」の変数の値を1増やして,更新するノード increment(インクリメント)は,プログラミング分野で,変数の値を1増やすという処理を意味する。反対に,1減らす処理のことをdecrement(デクリメント)という。ノードを検索するときは,インクリメントの「++」に対して,「--」と入力すればよい |
キャスト | 文字列の「型」を変更すること |
Integer型 | 整数のデータを保存するための「型」 |
String型 | 文字列のデータを保存するための「型」 |
文字列 | 「英数字」「かな文字」「記号」など,文字のみで構成されたデータ |
話を簡単にするため,数値で考えてみよう。
例えば,整数「10」があるとする。この「10」に小数「0.1」を足した場合,整数のままでは小数が入り込む隙間がないので「0.1」は消え去り,値は「10」のままだ。
この「10」を,小数を含む「10.0」に変換してから「0.1」を足せば,「10.1」というふうに小数を含む表現が可能となる。
型を変更することで,小数を含む数を足し算できるようになった。このように,少しデータを足してあげることで型を揃えられるものは,データピン同士を繋いだタイミングで,自動的に「キャスト」の処理を追加してくれる。
「整数」から「小数を含む数」へキャストする際に,小数部分のデータを足して調整するように,「Integer型」から「String型」へのキャストも,同じように少しデータを付け足して,調整しているイメ―ジである。
まず,イベントグラフを移動して,赤枠で示した「Camera Input」を探そう。
「EnhancedInputAction IA_Lookノード」は,マウスを動かすたびにトリガーされるイベントだ。マウスの入力のうち,横移動量を「Action Value Xピン」,縦移動量を「Action Value Yピン」で取得できる。
EnhancedInputAction IA_Lookノード | ||
テンプレートに用意されている,マウスの入力を取得するノード [Action Value Xピン] ・マウスの横移動量を取得できる [Action Value Yピン] ・マウスの縦移動量を取得できる |
横移動量は「Add Controller Yaw Inputノード」の「Valピン」へ,縦移動量は「Add Controller Pitch Inputノード」の「Valピン」へそれぞれ接続されている。
この「Valピン」に接続された値が「視点移動の量」である。
ここで「Valピン」へ接続される値を0.1倍すれば,「視点移動の量」が本来の0.1倍,つまり,感度を10分の1にすることができる。
以下の画像では,「Action Value X」「Action Value Y」をそれぞれ0.4倍した例である。画像を参考に感度調整を行ってみてほしい。
Multiplyノード | ||
掛け算を行うノード [左側のデータピン] ・掛け算に使用する数値 [右側のデータピン] ・掛け算の結果 |
「AddScoreイベント」を作成したが,このままでは動作しない。「的」を撃った時に動作するように,「的」のヒットイベントから「AddScoreイベント」を実行する処理を実装していこう。
グレイマン | ||
このキャラクターは「グレイマン」という名前だ。UE4で,サンプルとして用意されていたキャラクターモデルである UE5が正式リリースされてから2年以上経過している現在でも,よく見かける印象がある。意外と人気キャラなんだろうか だんだん愛着が湧いて,かわいく見えてしまっているのは,筆者だけではないだろう |
まず前提として,Unreal Engineのすべてのオブジェクトは,「Objectクラス」というものをベースとして作られている。万物の根源は「Objectクラス」だったのだ。
「Objectクラス」は万物なので,「的」「キャラクター」「銃」などすべてのオブジェクトを,ざっくり「Objectクラス」として取り扱うことができる。
対象を「特定のクラス」ではなく「ざっくりとしたクラス」にすることで,「クラス」の違いに関係ない同じような処理を,いちいち固有の処理として実装する必要がなくなるのだ。
一方,特定の「クラス」固有の処理を実行したい場合は,ざっくりとした認識ではなく,その「クラス」だと明確に認識しないといけない。
「お客様の中に,お医者様はいませんか」が,いい例だ。航空機などで急患が出た際,客室乗務員が呼びかけているシチュエーションを想定しよう。
一人ひとりに確認をして,もし手を上げてくれた人がいれば,その人への認識が「お客様」から「お医者様」に変化する。ここでやっと「患者を診る」という,「医者固有の処理」をしてもらえるようになるのだ。
今回は,「Cast To BP_FirstPersonCharacterノード」を使うことで,キャラクターが「BP_FirstPersonCharacterクラス」であるかどうかを確認している。
確認をしたことによって,「BP_FirstPersonCharacterクラス」に実装した,固有の処理である「AddScoreイベント」を実行できるようになるのだ。
「的」を落とした数をカウントできるようになった。
ゲームのクリア条件は,レベル上の「的」をすべて落とすことなので,レベル上の「的」の総数を取得して,その数にスコアが達したら「Clear!」と表示する処理を実装しよう。
処理は実行するタイミングも考慮しなければいけない。現実だと「いつ誰が確認するんだ」というイメージである。
スコアがクリア条件を満たしているか「毎フレーム」確認する方法もあるが,今回は「的」を撃ちぬいて「スコアが加算されたタイミング」で判定をしてみよう。
具体的に書くと,「AddScoreイベント」で「Score変数」を1加算した結果,レベル上の「的」の総数と同じかを判定し,もし同じなら「Clear!」と表示する流れである。
これで「的」を落とした数をカウントしていき,レベル上の「的」をすべて落としたら「Clear!」と表示されるというゲームルールが完成した。
次章からは,UIや演出を追加してさらにゲームっぽくしていこう。
本章の内容をすべて行った例を以下に示す。
・BP_SimpleTarget
- プレイヤーが操作しているキャラクターを情報を取得
- 取得した情報を判定し,BP_FirstPersonCharacterならAddScoreイベントを呼び出す
・BP_FirstPersonCharacter
- 感度調整
- Score変数の設定
- Score変数の加算
- レベル上のBP_SimpleTarget(的)の総数取得
- スコアがBP_SimpleTargetの総数に達したか判定
- 関連タイトル:
Unreal Engine
- この記事のURL: