【Unreal Engine5】初めてのゲーム開発 <第12回> ブロック崩しを作ろう①

練習用にブロック崩しゲームを作ってみます。
本来は2Dゲームとして作るべきかもしれませんが、UE5は3Dしか触ってないのでここで2Dを始めるとまた最初から覚えないといけないことが多そうなので妥協

今回だけでは完了しませんでした。
ゲーム基礎部分は次パートで終わりそうですが、ステージクリアとか、次のステージ読み込みとかが大変そう。

今回の記事でできること

・ステージ外枠の作成
・物理演算を使ったボールの挙動設定
・バーの動きとバーによるボールへの挙動変化の設定

《今回の記事後の実行テスト》

※動画出力時にフレームレートを10fpsに落としてます

まだブロックを作ってないので、ほぼほぼ一人エアホッケー。

注意点

今回の記事では入力キーの設定(Enhanced Input)に関する説明はしていません。
Enhanced Inputに関しては以前の記事で詳しく解説しています。

使用しているバージョン

Unreal Engine 5.3.2

目次

ステージ枠組を作成

新しく作成した3つのブループリント
BP_BaseBlock:床
BP_WallBlock:壁
BP_PlayerBar:プレイヤー用のバー

をそれぞれつなぎ合わせて作成。
形はCubeを変形させてるだけです。
イベントグラフは空です。

床・壁のmaterialに関しては無料アセットのNecro’s Utility Material Packを利用させてもらいました。
マス目があるだけで少しゲームっぽい雰囲気でますね。

カメラ設置

アクタ配置パネルをcameraで検索すると出てくるCamera Actorをビューポートに配置し、位置と角度を調整します。

Auto Activate for PlayerをPlayer0に設定すると、プレイヤーがカメラ視点に置き換わります。

デフォルトでは移動などは行えない為、疑似的な2Dゲームとして今回は使っていきます。

ボールの基本挙動の確認

ゲーム開始時に固定の運動エネルギーをAdd Impulseで与えて動きを見てみます。

今回はBP_NGBallというクラスを新規作成しました。

コンポーネントは球を追加しただけでシンプル。
Sphere(Static Mesh)のマテリアルはM_PBreakBlockBallとなっていますが、M_PBreakBlockBallで物理マテリアルを設定しています。

物理の項目設定
Simulate Physics ON
Mass 10kg(通常より軽く)
Linear Damping 0.0
Angular Damping 0.0
Enable Gravity OFF

重力OFFにしているのでZ軸方向の運動エネルギーには注意が必要。

物理マテリアル(一部)

Friction(摩擦)は0
Restitusion(反発力)は1

になるように設定

BP_NGBall

今回は初めて触るノード(Add Impulse/Set Physics Linear Velocity)のテスト。
ボールの運動制御では、瞬間的な運動エネルギー(ベクトル)を発生させるのが望ましいので、実現できそうな関数としてはこのあたりでしょうか。

UE5 ドキュメントより抜粋(機械翻訳)

Add Impulse
キャラクターに衝動を加えます。インパルスはティックごとに蓄積され、一緒に適用されるため、この関数への複数の呼び出しが蓄積されます。力積は、通常は 1 回加えられる瞬間的な力です。
このようにキャラクターの運動量を変更すると、移動モードが変更される可能性があることに注意してください。

Set Physics Linear Velocity
単体の線速度を設定します。これは慎重に使用する必要があります。AddForce または AddImpulse を使用した方がよい場合があります。


ピンの種類はほぼ同じであり、挙動も似ているのですが、Add Impulseは「蓄積Set Physics Linear Velocityは「設定というのが大きな違い。
前者は足し算・引き算、後者は代入。
ゲーム的には前者の方が面白いですが、後者の方が管理しやすい

失敗裏話

実は最初は「Get Actor Location」「Set Actor Location 」で実現させようと考えていたのですが、どうもSimulate Physics(物理演算)をONにすると、それらが思うように動作しなくなってしまうんですよね。
Simulate Physics(物理演算)と「Set Actor Location 」という物理法則無視の移動方法は二者択一ということになりそうです。

Simulate Physicsの設定(ON)は今回の挙動に不可欠でしたので「Add Impulse」「Set Physics Linear Velocity」を使うことにした次第です。

今回はAdd Impulseを採用。

《実行テスト》

一回あきらかにバグでバーをすり抜けてます。
球の速度が速すぎたのかな?
バーを厚くするか、ボールを大きくしたら修正できるでしょうか。

なお、こっそり中央付近にBP_ThirdPersonCharacterが立っていたりしますので、実は結構巨大なのが分かります。
そんなわけで加速度が大きすぎるのが原因かも。

バーを動かす

バー自体は通常のアクタ(BP_PlayerBar)で生成。
それを動かすためのプレイヤーPawnとして、BP_ThirdPersonCharacterを複製したBP_BarControl(親はCharacter)を作成。
ワールドセッティングのDefault Pawn ClassにはBP_BarControlを設定。

カメラは上で設定していてPlayer0をオーバライドしているような状態なので、あとはBP_BarControlで入力情報を取得してそれに合わせてBP_PlayerBarを動かします

注意点

現在の各BPの物理関係の設定をまとめてみます。

ボール(BP_NGBall)

マテリアルは物理マテリアルを設定しているマテリアルを指定。
Simulate PhysicsはON/重力OFF

バー(BP_PlayerBar)

Playerとついてますが、ただのactorです。

マテリアルもただ色をぬっただけで物理マテリアルは設定していません。

Simulate PhysicsはOFF

Set Actor Locationで動かす場合、Simulate PhysicsはOFFである必要があります(多分)。

壁(BP_WallBlockL/BP_WallBlockR)

他にもありますが、処理にかかわってくる左右の壁2種

こちらもバーと同じく、マテリアルは物理マテリアルの設定はなし。

Simulate PhysicsはOFF

ボール(Simulate Physics ON)とバー(Simulate Physics OFF)/壁(Simulate Physics OFF)との衝突判定(On Hit)は発生しますが、バーと壁はOFF同士なのでHitイベントは発生せず、バー移動方式はSet Actor Locationなので普通にめり込んでしまう

つまり、バーの移動制限は別で管理する必要があります
実装方法はいろいろあると思いますが、今回は座標を使う方法で。

イベントグラフ

入力アクション/入力マッピングコンテキストの設定に関しては、第5回で詳しく行っているので省略。
axis2Dで左右のみ設定した入力マッピングコンテキストを作成して下さい。

BP_BarControl(Player Pawn)

Event Begin Play(処理該当部のみ)
バーの挙動における左端/右端の数値を設定。

ローカル変数

Get Actor Of Classバー/左壁/右壁のクラスインスタンスを取得(3回使用)。
今回のテストマップではそれぞれ1つしかインスタンスを生成していません。
Get Actor Boundsバー(actor)の「中心座標(origin)」と「中心座標からの距離(Extent)」を取得。
Extentを分割することで、対象の大きさ(XYZ)の半分を取得
Get Actor Location左壁/右壁の位置(Y座標)を取得
Set Max L/Set Max R左壁のY座標+バーの幅の半分=左移動限界点
右壁のY座標-バーの幅の半分=右移動限界点
※正確には壁の幅の半分も加味すべきだが今回は簡略化

Enhanced Action Events IA_Movebarバーの左右移動)
キー入力により、バーを左右に移動させる。
左端より左、右端より右には移動しない。

Enhanced Action Events IA_MovebarキーボードのAD入力時のキー入力を受け取る。
Action Valueを分割すると、Action Value Xにaxis2Dの左右のキー情報が格納されている。
A:-1
D:+1
Get Actor Of Classバー(BP_PlayerBar)のインスタンスを取得。
Get Actor Locationバー(BP_PlayerBar)の中心点の位置情報。
In Range (Float)入力値(Value)が最低値(Min)と最大値(Max)の間にあればTrueを返す。
(移動後の)バーの中心点のY座標がMaxLとMaxRの間かチェック。
Branch(移動後の)バーの中心点のY座標が範囲内であれば、移動処理へ。
Set Actor LocationX座標(前後)/Z座標(高低)はそのままで、Y座標のみ移動。

《実行テスト》

バーによるボール操作の調整

バーにボールへの反発力を持たせる

現在ボールへの運動エネルギーはゲーム開始時のみ発生していますが、ゲームとしてはそれは面白くありません
なのでバーに衝突した際に運動エネルギーを増加させるような処理を考えます。

Simulation Generates Hit Eventsをオンに
これでBall側でOn Component Hitイベントが使えるようになります。

バーを3分割で作り直す

ボールが当たる位置によって処理を分けることで左右へのボールのちらしが発生するようにします。
今まではBP_PlayerBarという1つのアクタでしたが、BP_BarCenter/BP_BarLeft/BP_BarRightの3つに分解。

と言っても中身の処理はなく、見た目だけ分解したようなものです。
作り方
①BP_PlayerBarのビューポートで3つのCube(StaticMesh)でバーを作成
②BP_PlayerBarを2つ複製(合計3つのBP)し、名前をBP_BarCenter/BP_BarLeft/BP_BarRightに変更
③それぞれ左側/中央/右側の1つだけStaticMeshを残す(不必要な2つのStaticMeshは削除)
④ビューポート上に3つを配置し、形を整える

まず1つのBP上で形を整えると簡単に作れると思います。

ビューポートにこんな感じで配置します。

BP_BarCenter

BP_BarLeft

BP_BarRight

最初に1つのBPで作成して分割してるので、同じ位置(XYZ)にするとピッタリはまる。

バーを動かす処理を手直し

上で1つのBPを対象として作りましたが、BP_BarCenter/BP_BarLeft/BP_BarRightの3つのBPに対する処理になるので作り直す必要があります。

基本は上でやったバー移動と同じことを3つのBPに対して行うだけですが、イベントグラフは簡易的な説明にさせてください。

BP_BarControl(BP_ThirdPersonCharacterを複製して改造したもの)

Event Begin Play(処理該当部のみ)

ぐちゃぐちゃしてますが、基本は同じ
ここに関しては丸ごと移すよりは、理解して記述した方が良いと思います。

①Get Actor Of ClassでBP_BarCenter/BP_BarLeft/BP_BarRightを取ってきて、Get Actor Boundsでそれぞれの横幅の半分(Box Extent Y)を取得
②左の壁と右の壁に対しても横幅の半分を取得
③左の壁の中心座標(Y)+3つのパーツと壁の厚さの半分をMaxL(左移動限界点)に設定
④右の壁の中心座標(Y)-3つのパーツと壁の厚さの半分をMaxR(右移動限界点)に設定

やってることは、どこまで左右にいくと壁にめり込むか(その時のバーの中心座標)を変数として設定しています。
間違いなく①+②を1つの数値にまとめた方がスッキリしますが、ダラダラと前のグラフをコピペして作ったので見づらくなってしまいました。
というかAddノードやSubtractノードに普通に「ピンを追加」ってありましたね…

Enhanced Action Events IA_Movebarの処理に追加

動かすバーをBP_BarCenterに変更。
バーの移動速度にSpeed(ローカル変数:初期値1)を乗算する処理追加。
Speedに関しては加速ボタン用に作成しました。

下に続く。

同じようにBP_BarLeft/BP_BarRightも動かすのでコピペして作成。
In Rangeでの左端・右端判定は必要ありません。
左から続いてる緑データワイヤーは(-1 or 1)×Speed(ローカル変数)×20(固定値)が入っています。

Enhanced Action Events IA_Space

スペースを押してる間のみ、Speed(移動時に速度乗算)を3倍にする処理を追加。

ボールに運動エネルギーを与える処理

ボールに関する処理は自身(BP_NGBall)のイベントグラフで行います。

Event Begin Play

ほぼ変更なし。
使用関数はAdd Impulse(蓄積)を使うことに。
Set Physics Linear Velocity(上書き)も覚えておきます。

On Component Hit (Sphere)

Cast To BP_BarCenter
Cast To BP_BarLeft
Cast To BP_BarRight
ボールが当たった位置によって処理を分岐する。
Speedはローカル変数(デフォルト1000)
・中央バーに当たった場合、X軸方向に200
・左バーに当たった場合、X軸方向に-1000、Y軸方向に-1000
・右バーに当たった場合、X軸方向に-1000、Y軸方向に1000
Add Impulse (Sphere)X軸方向か、Y軸方向(正負)への運動エネルギーを加算する

ぐちゃぐちゃしてますがやってることはシンプル、というかイベント2種類だけであとはgetや演算系。

バーを3分割したのはこのためで、要は左バーに当たったら左方向に運動エネルギーを発生させ、右バーに当たったら右方向に運動エネルギーを発生させる。
中央部分は単純に加速
数値に関しては、ブロック崩しにおいてゲーム性に関わるため微調整が必要

バーの構成要素サイズは左3:中央8:右3で中央は200加速、左右は上手くつかうとX軸方向に関しては減速として使えるようにすることでゲーム性を上げてみました。
数値は適当で、このままだと左右に当てまくるとXがマイナスになってしまうのでどこかで制限する必要があります。

コメント

コメントする

目次