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

エレキベア
クマ〜〜〜〜!!

マイケル
さあC++ゲーム開発シリーズもついに第五回!
いよいよ3Dゲームを作ります!!
いよいよ3Dゲームを作ります!!
↑前回の記事

エレキベア
長い道のりだったクマ・・・。

マイケル
まあとはいっても基本的なゲームエンジン部分は前回までで作ってあるから、
あとはそれを利用して開発していくだけ!
一番楽しい部分になるね!
あとはそれを利用して開発していくだけ!
一番楽しい部分になるね!

マイケル
そして、今回作ったのは下記のゲーム!

マイケル
敵を全て破壊したらクリアという、
シンプルな3Dシューティングゲームになります!
第二回で作った2Dシューティングの3D版、のようなイメージです!
シンプルな3Dシューティングゲームになります!
第二回で作った2Dシューティングの3D版、のようなイメージです!

エレキベア
ちゃんとゲームっぽくなってるクマ〜〜

マイケル
ソースはこれまでと同様GitHubにあげてありますので
是非こちらも参考に読んでみてください!
是非こちらも参考に読んでみてください!

エレキベア
楽しみクマ〜〜〜
参考書籍

マイケル
書籍について、今回はゲームの作り込みだったのであまり使っていませんが、
ところどころ下記書籍を読み返しながら開発しました!
ところどころ下記書籍を読み返しながら開発しました!

マイケル
前回まで使い続けた彼らは
もはやバイブルと化しています・・・。
もはやバイブルと化しています・・・。

エレキベア
愛着も湧いてくるクマね・・・
作るゲームの仕様

マイケル
作る前に、どんなゲームを作るのかざっと説明します!
プレイヤーは常に中心

マイケル
プレイヤーの位置は常に(0, 0)!
そこにカニが目掛けて襲いかかります!
そこにカニが目掛けて襲いかかります!
向きを変えてショット攻撃

マイケル
プレイヤーは向きを変えてショット攻撃ができます!
カニが全滅するかプレイヤーが破壊されるかで結末が変わる仕様です。
カニが全滅するかプレイヤーが破壊されるかで結末が変わる仕様です。

マイケル
つまり空間は3Dだけど、基本的には2Dゲームの考えで開発します!
それに加えて カニの移動や攻撃を撃てる方向に縦軸を追加 する
といった味付けを加えることで3D感を出していきます。
それに加えて カニの移動や攻撃を撃てる方向に縦軸を追加 する
といった味付けを加えることで3D感を出していきます。

エレキベア
それくらいなら作りやすそうクマね
シーン遷移

マイケル
そしてシーン遷移は下記の通り!
こちらも2Dゲーム開発の時と同じだね!
こちらも2Dゲーム開発の時と同じだね!

エレキベア
なんだか作れそうな気がしてきたクマ

マイケル
作る内容が決まったところで
早速制作にとりかかろう!
早速制作にとりかかろう!
素材の作成

マイケル
まずは必要な素材について!
必要最低限なものだけざっと作ってしまいましょう!
必要最低限なものだけざっと作ってしまいましょう!
3Dモデル

マイケル
3DモデルはBlenderを使用して作成しました。
・プレイヤー
・カニ
・ミサイル
・爆発エフェクト
※Planeに画像貼り付け
・SkyBox
※球体の裏側にテクスチャ貼り付け
その他画像

マイケル
そして画像については2Dゲーム開発時のを使い回しているのと、
追加でいくつか作成しています!
追加でいくつか作成しています!
・マーカー
・各種メッセージ

マイケル
使う素材はこれだけ!
あとはガンガン作っていきましょう!
あとはガンガン作っていきましょう!

エレキベア
やったるクマ〜〜〜!!
シューティングゲームの開発

マイケル
それでは準備ができたところでゲームの中身に触れていきます!

エレキベア
楽しみクマ〜〜〜〜〜

マイケル
基本的なゲームループやシーン遷移の考え方については、
【C++】第二回 C++を使ったゲーム開発 〜SDLを使った2Dゲーム開発編〜
3Dゲームエンジン部分の基礎については
【C++】第三回 C++を使ったゲーム開発 〜3Dゲーム開発基礎 OpenGLと座標変換編〜
【C++】第四回 C++を使ったゲーム開発 〜3Dゲーム開発基礎 fbx読込とシェーダ編〜
をそれぞれ参照してもらって、
今回はそれ以外の、3Dゲームを作る上での考えや工夫した点について解説していくよ!
【C++】第二回 C++を使ったゲーム開発 〜SDLを使った2Dゲーム開発編〜
3Dゲームエンジン部分の基礎については
【C++】第三回 C++を使ったゲーム開発 〜3Dゲーム開発基礎 OpenGLと座標変換編〜
【C++】第四回 C++を使ったゲーム開発 〜3Dゲーム開発基礎 fbx読込とシェーダ編〜
をそれぞれ参照してもらって、
今回はそれ以外の、3Dゲームを作る上での考えや工夫した点について解説していくよ!

エレキベア
これまでの知識を使ってどう作ったかというところクマね
フォルダ構成

マイケル
フォルダ構成は下記の通り!
基本的に前回と大きく変わってはいなくて、Scenesフォルダを追加したのと、
衝突判定用のコンポーネントを追加しただけの構成になっています!
基本的に前回と大きく変わってはいなくて、Scenesフォルダを追加したのと、
衝突判定用のコンポーネントを追加しただけの構成になっています!
↑フォルダ構成

マイケル
そして使用したライブラリは下記の通り!
こちらも前回と変わりはありません。
こちらも前回と変わりはありません。
[使用ライブラリ]
・SDL、SDL_Image
・GLEW
・fbxsdk

エレキベア
OpenGLとSDLの組み合わせクマね
SkyBoxの作成

マイケル
まずは背景、SkyBoxの作成について!
画面上で動いている星々になります。
画面上で動いている星々になります。

エレキベア
これはどうやって設定しているクマ?

マイケル
球体の裏面に星のテクスチャを貼って回転
させることでそれっぽく見せているよ!
させることでそれっぽく見せているよ!

マイケル
合わせて視差スクロールの考えも応用して、
2つの球体を異なるスピードで回転させることで奥行きを表現しています!
2つの球体を異なるスピードで回転させることで奥行きを表現しています!

エレキベア
なるほどクマ!
案外簡単な仕組みだったクマね
案外簡単な仕組みだったクマね

マイケル
コードは下記の部分!
回転するActorを異なる速度で2つ生成しています!
回転するActorを異なる速度で2つ生成しています!

エレキベア
これで背景は完成クマ〜〜〜
プレイヤーの操作

マイケル
そして次はプレイヤーの操作について!
位置は(0, 0)固定だから、入力に合わせて
・回転する処理
・攻撃する処理
を実装しています!
合わせて、回転中は機体の傾きも変えるようにしています。
位置は(0, 0)固定だから、入力に合わせて
・回転する処理
・攻撃する処理
を実装しています!
合わせて、回転中は機体の傾きも変えるようにしています。
入力に応じた処理

マイケル
入力に応じた挙動について、コードは下記の通り!

マイケル
これまでの記事を読んだ方は気づいた方はいるかもしれませんが、
実は第二回の2Dゲーム作成の時と内容はほぼ同じです!
3Dになって軸が増えても、基本的な考えは同じように実装できるということですね。
実は第二回の2Dゲーム作成の時と内容はほぼ同じです!
3Dになって軸が増えても、基本的な考えは同じように実装できるということですね。

マイケル
あとは回転が変わったプレイヤーの後ろを常にカメラがついていくように、
Cameraクラスの挙動も実装してあげましょう。
Cameraクラスの挙動も実装してあげましょう。

エレキベア
3Dな分、カメラの挙動は少し考える必要がありそうクマね
オイラー角での指定とクォータニオン変換

マイケル
一点、エンジン部分で前回と挙動を変えている部分については、
オイラー角で角度を指定できるようにしたということです。
Actorの角度情報は基本的にオイラー角で管理し、
座標変換する際にクォータニオンに変換して計算しています。
オイラー角で角度を指定できるようにしたということです。
Actorの角度情報は基本的にオイラー角で管理し、
座標変換する際にクォータニオンに変換して計算しています。
↑オイラー角での設定とクォータニオンへの変換

エレキベア
計算負荷は増えそうクマがとりあえずは仕方なさそうクマね・・・
ミサイルの距離判定

マイケル
発射したミサイルについては、基本的に真っ直ぐ進むようにし、
中心から一定距離離れたら破棄するようにしています。
中心から一定距離離れたら破棄するようにしています。

マイケル
今回の場合は中心が(0, 0)のため、
単純に位置をベクトルした時の長さを求めることで判定することができます。
単純に位置をベクトルした時の長さを求めることで判定することができます。
↑位置ベクトルの長さで距離を判定

エレキベア
ここで数学が出てくるクマね

マイケル
ベクトル計算については下記記事でも解説しているので
こちらも是非ご参考ください!!
こちらも是非ご参考ください!!
カニの動き

マイケル
次は敵(カニ)の動きについて!
基本的な挙動としては
・中心(0, 0)に向かって進む
・中心(0, 0)付近に到着したら移動をやめてくるくる回る
といったものになっています。
合わせて、縦・横方向の揺れも指定 できるようにしました。
基本的な挙動としては
・中心(0, 0)に向かって進む
・中心(0, 0)付近に到着したら移動をやめてくるくる回る
といったものになっています。
合わせて、縦・横方向の揺れも指定 できるようにしました。
角度指定での生成

マイケル
カニの生成については、上から見た時の角度指定で生成
できるようにしています。
下記のように一定距離離れたところに生成するイメージですね。
できるようにしています。
下記のように一定距離離れたところに生成するイメージですね。

マイケル
この設定処理の部分は下記になります。
生成時の正面ベクトルに、指定した角度のクォータニオンをかけ合わせる
ことで位置を求めています。
生成時の正面ベクトルに、指定した角度のクォータニオンをかけ合わせる
ことで位置を求めています。

マイケル
合わせて、atan2を使用することで位置から向きも求めて設定しています。
アークタンジェントの考えについては下記記事をご参照ください!
アークタンジェントの考えについては下記記事をご参照ください!

エレキベア
atan懐かしいクマ〜〜〜〜

マイケル
生成ができたら、指定した向きの方向へ進行させて
中心に来た時に動きを止めるだけ!
ここでは移動量から判定するよう実装しています!
中心に来た時に動きを止めるだけ!
ここでは移動量から判定するよう実装しています!
カニのランダム生成

マイケル
あとはこれらを指定して生成するだけ!
下記のパラメータを乱数で指定して生成しています!
・出現位置
・速度
・大きさ
・揺れ幅
下記のパラメータを乱数で指定して生成しています!
・出現位置
・速度
・大きさ
・揺れ幅
↑乱数を使用した生成

マイケル
ただ、調整はしているとはいえ、完全に乱数任せにしてしまう方法はよくありません。
というのも、面白い時と面白くない時のムラが出来てしまうためです。
極力、最大限楽しめるようにゲームデザインを作り込むべきところなので、
リリースする際には気をつけるようにしましょう!
というのも、面白い時と面白くない時のムラが出来てしまうためです。
極力、最大限楽しめるようにゲームデザインを作り込むべきところなので、
リリースする際には気をつけるようにしましょう!

マイケル
また、こういったパラメータは外出しして調整しやすくした方が望ましいでしょう・・・

エレキベア
(結局今回は手抜きなのかクマ・・・)
AABBでの衝突判定

マイケル
次は衝突判定について!
今回だと
・カニがプレイヤーに当たった時
・ミサイルがカニに当たった時
の2つの判定が必要になります。
今回だと
・カニがプレイヤーに当たった時
・ミサイルがカニに当たった時
の2つの判定が必要になります。

マイケル
衝突判定には様々な種類がありますが、
今回は物体の形状と処理負荷が重くないことから、
AABBでの衝突判定を実装しました。
今回は物体の形状と処理負荷が重くないことから、
AABBでの衝突判定を実装しました。

マイケル
AABBは軸平行バウンディングボックスと呼ばれるもので、
下記のようにオブジェクトが回転しても、コライダ自体は回転せずに大きさが変わる
ものになります。
下記のようにオブジェクトが回転しても、コライダ自体は回転せずに大きさが変わる
ものになります。

マイケル
コライダごと回転するOBBといった考えもありますが、
こちらはAABBと比べて計算負荷が高くなってしまいます。
またその他の衝突判定の例として過去記事で実装しているので、
興味があればご参照ください!
こちらはAABBと比べて計算負荷が高くなってしまいます。
またその他の衝突判定の例として過去記事で実装しているので、
興味があればご参照ください!

エレキベア
ゲームエンジン使いたくなるクマ・・・・・・

マイケル
AABBの実装は簡単で、下記のように各軸ごとに最小値、最大値をもたせて判定するものになります。
これらの値は、モデルを読み込む際に座標を渡してあげるだけで設定することができます。
これらの値は、モデルを読み込む際に座標を渡してあげるだけで設定することができます。

マイケル
そしてActorが回転した際には各値も回転させることで
形状を変更させることができます!
形状を変更させることができます!

マイケル
あとはこれらを使って判定を行うだけ!
シンプルかつ計算負荷も軽い便利な判定方法ですね!
シンプルかつ計算負荷も軽い便利な判定方法ですね!

エレキベア
これは扱いやすそうクマ〜〜〜
マーカーの付与

マイケル
これで一通りゲームはできる状態ですが、
+αで遊びやすさやクオリティをあげてみましょう!
+αで遊びやすさやクオリティをあげてみましょう!

マイケル
まずは敵のマーカー表示!
ゲームの特性上、画面外の敵の位置が分からないと遊びづらいので、
判定して表示するようにします。
ゲームの特性上、画面外の敵の位置が分からないと遊びづらいので、
判定して表示するようにします。

マイケル
これは各エネミーのクリップ座標を求めて画面の範囲外の値だった場合に表示する
といった実装にしています。
試行錯誤の結果、
X軸で外れている場合には画面端に調整、
Z軸で外れている場合にはXY値の符号を反転
することで表示することにしました!
といった実装にしています。
試行錯誤の結果、
X軸で外れている場合には画面端に調整、
Z軸で外れている場合にはXY値の符号を反転
することで表示することにしました!

マイケル
距離に合わせてマーカーの大きさも変えることで、
どのくらいの位置に敵がいるのかを分かるようにもしています。
どのくらいの位置に敵がいるのかを分かるようにもしています。

エレキベア
マーカー無かったらマジでクソゲークマね
登場演出の作成

マイケル
最後に登場演出の作成について!
せっかく3Dなので奥行き感を見せたい!
かわいいモデルも作ったので見せたい!
という私の欲求になります・・・。
せっかく3Dなので奥行き感を見せたい!
かわいいモデルも作ったので見せたい!
という私の欲求になります・・・。

エレキベア
これは何か難しそうクマね

マイケル
それが意外とそうでもなくて、ゲーム開始時のみカメラ位置を移動させているだけなんだ。
カメラの注視点だけしっかり設定してあげれば、簡単に実装することができるよ!
カメラの注視点だけしっかり設定してあげれば、簡単に実装することができるよ!

マイケル
あとはこれをSceneから呼んであげるだけ!
カメラ視点が変わるので、ライティングも一時的に変更しています。
カメラ視点が変わるので、ライティングも一時的に変更しています。

エレキベア
ちょっとしたことでクオリティが上がるのはいいクマね〜〜〜
反省点と課題

マイケル
とここまでで一通りの解説は終了です!
最後に今後作る人に向けて、今回の妥協点や課題についても共有しておきます!
最後に今後作る人に向けて、今回の妥協点や課題についても共有しておきます!
サウンドが無い

マイケル
サウンドについては別ライブラリの導入が必要であろうこともあり
今回は妥協しました・・・
今回は妥協しました・・・

エレキベア
あまり複雑にもしたくないクマね

マイケル
まあどうせブログに載せるだけなので無くても分からないしね!

エレキベア
・・・・・。
fbx読込の効率化

マイケル
それから3Dモデルの読み込みについて、ゲーム中にfbx読み込みを行なっていますが、
これは非常に効率が悪いです!
これは非常に効率が悪いです!

マイケル
そのため下記のように、事前にJSON形式等のゲームで扱いやすい形に変換しておく方がよいでしょう・・・。

エレキベア
規模が大きくなったらとても毎回読み込むのはしたく無いクマね
レベルデザイン

マイケル
これは上の方でも説明した通り、乱数決め打ちでエネミーを生成している点です!
ステージ作成、難易度調整といったレベルデザインは行った方がよいです。
ステージ作成、難易度調整といったレベルデザインは行った方がよいです。

エレキベア
手抜きクマね
計算処理の効率化

マイケル
クォータニオン変換や座標読み込み等、自分があげたコードには
効率がよくない箇所がまだまだあります。
オリジナルのゲームエンジンを使用するとなると、そういった部分をどんどん改善していく必要があると思います。
効率がよくない箇所がまだまだあります。
オリジナルのゲームエンジンを使用するとなると、そういった部分をどんどん改善していく必要があると思います。

マイケル
それとゲームを量産する場合には、
こういった機能はライブラリ化しておいた方がよさそうですね。
こういった機能はライブラリ化しておいた方がよさそうですね。

エレキベア
なんという長い道のりクマ・・・
エフェクト作成、透過処理

マイケル
今回、エフェクトについて透過画像を使用しましたが、
アルファブレンドとZバッファを同時に使用するのは思わぬレンダリングミスが起こりえます。
そのため3Dモデルではアルファブレンドは切って、モデルとして描画する必要があります。
アルファブレンドとZバッファを同時に使用するのは思わぬレンダリングミスが起こりえます。
そのため3Dモデルではアルファブレンドは切って、モデルとして描画する必要があります。

マイケル
今回のゲームだと、爆発エフェクトがうまく透過処理されない場合があるのは、
これのせいになりますね・・・。
これのせいになりますね・・・。

エレキベア
透過画像を貼り付けるだけでは危険があるクマね
おわりに

マイケル
というわけで今回は3Dゲーム開発編でした!!
どうだったかな??
どうだったかな??

エレキベア
やっと3Dでゲームが作れて感動だったクマ〜〜〜〜
長い道のりだったクマ・・・。
長い道のりだったクマ・・・。

マイケル
これでC++ゲーム開発シリーズは一旦終わり!
・・・にしようと思っていたけど、最後に
このゲームをUnityで作ったらどうなるか?
についてだけ試して紹介しようと思うよ!
・・・にしようと思っていたけど、最後に
このゲームをUnityで作ったらどうなるか?
についてだけ試して紹介しようと思うよ!

エレキベア
確かにどのくらい感覚が違うのかも、
クオリティがどこまでアップできるかも気になるところクマね
クオリティがどこまでアップできるかも気になるところクマね

マイケル
つまり次回こそが最終回だ!!
こちらもお楽しみに〜〜〜〜!!!
こちらもお楽しみに〜〜〜〜!!!

エレキベア
クマ〜〜〜〜〜〜
【C++】第五回 C++を使ったゲーム開発 〜OpenGLを使った3Dゲーム開発編〜 〜完〜