Unity未経験がブロック崩しを作ってみた

OVERVIEW

ブロック崩し

YEAR 2021

はじめに

Unityを触ったことのないど素人ですが、色々調べて1からブロック崩しを作ってみました。

ブロック崩しを作りながら、Unityの作業の流れや、基本的な所を理解していこうと思いました。

完成品

まずは完成品から。このようなものを作りました。

矢印キーでプレイヤー(下のバー)を動かしてボールを弾き、水色のブロックを全て消せばゲームクリア。ボールが下の壁に当たるとゲームオーバーです。

ゲームクリア、ゲームオーバー時は以下のようになり、2秒後にメニュー画面へ遷移します。

メニュー画面も超簡素ですが作りました。

作業の流れ

作業の流れは、以下の通りです。

①以下の3Dオブジェクトを作成

 ・床(キラキラしてる部分)、壁(床の子オブジェクトとして作成)、プレイヤー(バー)、ボール

②プレイヤー、ボールのマテリアルを作成

③ブロックのプレハブを作成

④ゲーム開始時、ブロックのプレハブからオブジェクトを作成するスクリプトを作成(横5*縦2の10個作成)

⑤ボールにリジッドボディ、物理マテリアルを追加

 ※何に当たっても必ず跳ね返り、摩擦0で進み続けるようにする

⑥以下の機能をスクリプトで実装

 ・プレイヤー(バー)の移動

 ・ボールの初動(ゲーム開始時右上に飛ばす)

 ・ボールがブロックに触れたらブロックを削除

 ・ボールが下の壁に触れたらボールを削除

 ・ブロックがなくなったらゲームクリア、ボールがなくなったらゲームオーバーの

  テキストを表示し、2秒後メニュー画面に遷移

  ※実装にあたり、以下も実施

   ・ブロック、ボールオブジェクトにそれぞれタグを設定

   ・GAMECLEARやGAMEOVERを表示するテキストの作成

   ・メニュー画面の作成

   ・ビルド設定を開き画面遷移ができるようにする

 ・メニュー画面でボタンを押してゲーム画面へ遷移

⑦アセットストアの無料アセットでゲーム画面のレイアウトを変更


プロジェクトの新規作成

3Dを選択、プロジェクト名を適当に入力し、プロジェクトを新規作成します。

するとUnityのエディター画面が出てきます。

※画像は画面右上の「Default」を「Tall」にし、画面のレイアウトを変更しています。

プロジェクト作成時に「SampleScene」という空のシーンが自動的に作られます。

シーンとは、1画面単位のセーブファイルみたいな感じですかね。

名前を「Game」に変更します。

オブジェクトの作成

まずは床を作成します。

ゲームオブジェクト > 3Dオブジェクト > キューブ を選択。

するとキューブが出てきました。これを引き伸ばして床を作ります。

「Transform」の数値を変えると、キューブの位置や向き、大きさが変わります。

スケールの値を変更すると、床っぽくなりました。

ついでに床の名前を「Cube」から「Floor」に変更。

次に壁を作成します。

「Floor」の下に3Dオブジェクトのキューブ「Wall Left」を作成。

位置やスケールを調整し、左側の壁ができました。

「Floor」の下に作ることで親オブジェクトと子オブジェクトの関係になり、親つまり床の位置や大きさを変えると、それに追従して子つまり壁の位置や大きさも変わります。そのため管理が楽になります。

残り3つの壁も作っていきます。

「Wall Left」をコピペし「Transform」内の数値を調整すると、壁ができあがりました。

次に、プレイヤーが動かすバーを作成します。

3Dオブジェクト > キューブ を選択して作成。名前は「Player」にし、位置とスケールを調整。

マテリアルの設定

「Player」の色を変えたいので、マテリアルを設定します。

マテリアルとは材質のことで、色や光沢、光を放っているか等を設定できます。

まずはプロジェクトタブの「Assets」を右クリック > 作成 > フォルダー を選択します。

フォルダーが作成されるので、名前を「Materials」にします。

「Materials」フォルダを右クリック > 作成 > マテリアル を選択。

マテリアルが作成されるので、名前を「Player」にします。

色を変更します。アルベドをクリックし、試しに緑を選ぶと「Player」も緑になりました。

緑にしたマテリアルを、オブジェクトに反映させます。

「Player」オブジェクトの要素0にマテリアルをドラッグ&ドロップ。

すると、「Player」オブジェクトも緑に変わりました。

ボールのオブジェクトも作成(3Dオブジェクト > スフィア を選択)し、位置やサイズを調整。

その後マテリアルを作成し、赤色を設定。それをオブジェクトに反映させました。

Prefab (プレハブ)でブロックを作成

同じオブジェクトを大量に作成する場合、Prefab(プレハブ)を使用して効率的に作成します。

Prefabとは設計書のようなもので、今回はブロックの設計書を1つ作成しておき、その設計書を元にオブジェクトをプログラムで大量に作成します。

まずはブロックのオブジェクトを1つ作成(3Dオブジェクト > キューブ)し、サイズを調整。

マテリアルで色も変更しておきます。名前はオブジェクトもマテリアルも「Block」にします。

次に、プロジェクトタブの「Assets」内に新規フォルダ「Prefabs」を作成します。

作成した「Prefabs」フォルダに、「Block」オブジェクトをドラッグ&ドロップします。

「Prefabs」フォルダ内に「Block」のプレハブアセットが作成されました。

プレハブを作成したので、オブジェクトの「Block」は削除します。

次に、「Assets」フォルダ内に「Scripts」フォルダを作成します。

「Scripts」フォルダを右クリックし、作成 > C#スクリプト を選択します。

スクリプトが作成されるので、名前を「BlockInit」にします。

7~20行目を書き足しました。上記を説明すると

10行目 : AwakeはStartより早く呼ばれるイベント関数

12行目~15行目 : for文で横5×縦2回分繰り返す

16行目 : 「g」という変数を宣言。その中にBlockのPrefabをインスタンス化(実体化)

17行目:Blockの座標を指定

となります。

「BlockInit」スクリプトを「Floor」オブジェクトにドラッグ&ドロップします。

すると「BlockObjPrefab」「BlocksObj」が新たに表示されます。

これはスクリプト内で宣言したpublic変数です。ここに「Block」プレハブ、「Blocks」オブジェクトをドラッグ&ドロップすることで、スクリプトと連動させることができます。

この状態で実行(▷ボタンをクリック)すると、ブロックが追加されたのが確認できます。

リジッドボディ、物理マテリアルの追加

次に、ボールに物理エンジンを適用します。適用すると、ボールが壁やブロックに当たった時に跳ね返るようになります。

「Ball」オブジェクトを選択した状態で、コンポーネント > 物理 > リジッドボディ を選択。


インスペクタータブにリジッドボディが追加されました。これでボールに物理エンジンが適用され、重力の影響を受けたり、力を加えられたら動いたりします。


次に、物理マテリアルを追加します。

物理マテリアルは、物理演算で摩擦や跳ね返りを設定できます。

ボールの摩擦をなくして進み続けるようにし、何に当たっても必ず跳ね返るようにします。

「Materials」プロジェクト内で右クリック > 作成 > 物理オブジェクト を選択。名前は「Ball」にします。値は以下のように設定します。

各項目を上から説明すると、

・動いてる時の摩擦。止まらずに進み続けてほしいので0にします。

・止まってる時の摩擦。これも0にします。

・弾力性。数値が高い程弾みます。普通で良いので1にします。

・ぶつかった時の摩擦力。最小にすると、ぶつかった物同士の内、低い方の摩擦力にボールの弾力性が変化します。

・ぶつかった時の弾力性。最大数にすると、ぶつかった物同士の内、高い方の弾力性にボールの弾力性が変化します。

となります。上記のように設定すると、何に当たっても必ず跳ね返り、摩擦が全くないので進み続ける物理マテリアルが完成します。

これを「Ball」オブジェクトの「Sphere Collider」内のマテリアルに追加します。

スクリプトの作成

スクリプトとはC#言語を使用したプログラムで、オブジェクトを意図通りに動かす時等に使用します。今回スクリプトで実装したプログラムは以下です。

・プレハブを元にブロックのオブジェクトを複数作成

・プレイヤー(バー)の移動

・ボールの初動

・ボールがブロックに触れたらブロックを削除

・ボールが下の壁に触れたらボールを削除

・ゲームクリア or ゲームオーバー時にそのテキストを表示し、2秒後メニュー画面に遷移

・メニュー画面でボタンを押してゲーム画面へ遷移

ブロックの複数作成は既に終了してるので、残りをここではやっていきます。


まずは、プレイヤー(バー)の移動を実装します。

プロジェクトの「Scripts」フォルダ内で右クリック > 作成 > C#スクリプト を選択。

名前は「PlayerManager」にし、以下のように記述します。

7行目:バーを動かす速さの変数。publicにすることでインスペクターに変数が表示されます。speedではなく速度になってますが、恐らくUnityの日本語化の影響かと思われます。インスペクターで数値がいじれることで、ゲーム実行中でも値が変更でき、調整がしやすくなります。スクリプトに値直書きの場合、ゲーム実行を止めて値変更して実行して、を繰り返す必要があり、今回は1項目ですが項目が多い場合等は特に、publicにする方がバランス調整しやすいです。

18~27行目:左矢印キーが押されたらバーも左に移動、右矢印が押されたら右に移動します。Time.deltaTimeは、今と前のフレームの時間差を返します。Updateは毎フレーム呼ばれるメソッドですが、フレームレートが一定でない場合、Updateメソッドを呼び出す回数も変動します。その時間差をバーをどのくらい移動させるかの式に乗算することで、差分をカバーできます。


次に、ボールの初動を実装します。

具体的にはゲーム開始時に、右斜め上に飛んでもらうプログラムを実装します。

「BallManager」というスクリプトを作成し、中身は以下のように記述します。

7行目:ボールの飛ぶスピードの変数を宣言。

8行目:ボールのリジッドボディを格納する変数を宣言。

13行目:8行目の変数にボールのリジッドボディを格納。

14行目:ボールに右斜め上に力を加える処理。


次に、ボールがブロックに触れたらブロックを削除、下の壁に触れたらボールを削除するスクリプトを実装します。

先程の「BallManager」スクリプトに以下を記述します。

OnCollisionEnterは、何かが触れた時に呼ばれるメソッドです。


次に、ゲームクリア or ゲームオーバー時にそのテキストを表示し、2秒後メニュー画面に遷移するスクリプトを実装します。

「GameController」というスクリプトを作成し、中身は以下のように記述します。

20行目:ブロックの数を変数に格納。(「Block」のタグが付いてるオブジェクトの数をカウント)

21行目:ボールの数を変数に格納。(「Ball」のタグが付いてるオブジェクトの数をカウント)

23行目:ブロックが0個 or ボールが0個の時、以降の処理を行う。

26、27行目:テキストの文字をブロックが0なら「GAMECLER」、それ以外(ボールが0)なら「GAMEOVER」を設定。

28行目:テキストを非表示から表示に変える。

31~33行目:2秒後にメニュー画面へ遷移。


これで終わりではなく、上記スクリプトを実現させるには、タグの設定、テキストの作成、メニュー画面の作成が必要になります。

まずは、タグの設定を行います。

ブロックやボールのオブジェクトに「Block」や「Ball」のタグを付けることで、上述のスクリプトでタグをカウントし、タグの数が0 = ブロックがなくなった、ボールがなくなった、という判定ができるようになります。

「Block」プレハブのタグの右にある▽を押しタグを追加を選択、「Block」というタグを追加します。その後▽を再び押し「Block」タグを選択します。

「Ball」も同様の手順で設定します。


次に、GAMECLEARやGAMEOVERを表示するテキストの作成を行います。

ヒエラルキータブで右クリック > UI > テキスト を選択。名前は「ClearUI」にします。

位置や幅、高さ、フォントサイズ、色等をお好みで設定。

その後、インスペクタータブの最上部にある「ClearUI」左のチェックボックスのチェックを外します。外すことで、このテキストは非表示になります。

前述のスクリプト28行目で、ゲームクリア or オーバー時に表示させています。


最後に、メニュー画面の作成を行います。上述のスクリプト33行目で遷移する先の画面になります。

プロジェクトタブの「Scenes」フォルダ内で右クリック > 作成 > シーン を選択。名前は「MenuScene」にします。

画面遷移を可能にするには、設定が必要になります。ファイル > ビルド設定 を選択。

シーン2つをドラッグ&ドロップします。最上部にあるシーンがアプリ起動時に表示されるシーンになるため、メニューシーンが上にくるようにします。


次にメニュー画面のオブジェクトを簡単に作成します。

プロジェクトタブの「Scenes」内で右クリック > 作成 > シーン を選択。「MenuScene」というシーンを作成します。

「MenuScene」をダブルクリックし、メニュー画面を編集できるように切り替えます。

ヒエラルキータブで右クリック > UI > テキスト を選択。文字を「メニュー画面」にし、大きさや位置、色などを調整します。

ヒエラルキータブで右クリック > UI > ボタン を選択。ボタンの文字を「Game start」にし、大きさや位置を調整します。

次にスクリプト「MenuManager」を作成。ゲーム画面へ遷移する処理を書きます。

空のゲームオブジェクト「MenuManager」を作成し、その中にこのスクリプトを追加します。

そのゲームオブジェクトを、ボタンのインスペクタータブのクリック時の部分にドラッグ&ドロップ。その後「GameStart」メソッドを選択します。

これでボタンを押すとゲーム画面へ遷移することが可能になりました。

アセットストアの無料アセットで画面のレイアウトを変更

最後に、unity asset storeで無料の「NatureStarterKit2」をインポートして、ゲーム画面のレイアウトを変えてみました。

これで完成です。長くなりましたが、最後まで閲覧いただきありがとうございました。