YouTubeのひろはすさんの動画を見て、Unityでブロック崩しゲームを作成しました。
結論
私は超初心者でしたが、すごくわかりやすかったです。
言われるままに作ったらちゃんと動くゲームができました。
途中、動画を何度も止めて見返したり、エラーが出たらググって修正しました。
次回予定
知識を定着させるために、作り方動画は見ずに、自力で何度か作ってみる。
デザインや動き、UIなど、いくつか改造する。
自分用の覚え書き
インストール
Unity Hubインストール後、Unity Hubを起動して、その中からUnityをインストール。
新規プロジェクト作成
Unity Hubから新規プロジェクトで、3Dを選択する。
オブジェクトの追加
Sceneウィンドウに、床、壁、プレーヤー、ブロック、ボールを配置する。
3DオブジェクトのCubeやSphereを追加し、Hierarchyウィンドウで各オブジェクトを選択し、Inspectorウィンドウで大きさや位置を設定する。
色の設定
ProjectウィンドウでAssets配下にマテリアルを追加し、Inspectorウィンドウ内のAlbedoで色を指定する。
Hierarchyウインドウで色をつけるオブジェクトを選択しておき、マテリアルをInspectorウィンドウにドラッグしてくっつける。
ボールの動き
InspectorでAdd Component->Physics->Rigidbodyでリジッドボディを追加し、
Constrainsで動かしたくない方向軸に制約をつける。
ProjectのAssets配下にPhysic Materialを追加し、摩擦を0に、反発を1にする。
Physic MaterialをボールのInspectorのSphere ColliderのMaterialにドラッグしてくっつける。
ProjectのAssets配下にC#スクリプトを追加し、名前を変更する。
※名前を後で変更する場合は、スクリプト内も変更が必要。
スクリプトは下記の通り。ゲームスタート時に、斜め前に動かすだけ。
public class Ball : MonoBehaviour
{
public float speed = 1.0f;
private Rigidbody myRigidbody;
public GameManager myManager;
// Start is called before the first frame update
void Start()
{
myRigidbody = this.GetComponent<Rigidbody>();
myRigidbody.AddForce*1
{
if(this.transform.position.x > -4)
this.transform.position += Vector3.left * speed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.RightArrow))
{
if (this.transform.position.x < 4)
this.transform.position += Vector3.right * speed * Time.deltaTime;
}
}
}
ブロックの動き
何かにぶつかったら、自ら消えるだけ。
スクリプトは下記のとおり。
public class Block : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
private void OnCollisionEnter(Collision collision)
{
Destroy(this.gameObject);
}
}
★ここまでの記述でゲームの基本となる動作が可能になる。
★★★覚えたこと
- 形として見える物はSceneウィンドウにオブジェクトとして配置する。同時にHierarchyにも反映される。
- 属性や性質は、まずProjectウィンドウのAssets配下に置いて、これをHierarchyのオブジェクトにくっつける。
- ボールやプレイヤーのspeedのように、後で簡単に変更したい変数は、public変数として定義し、Inspectorで設定する。
ゲームマネージャーの追加
ゲームクリアとゲームオーバーの処理を行うため、ゲーム全体を管理するスクリプトを追加する。名前は何でもよいがGameManagerとする。
物体として形はないが、スクリプトをくっつける先が必要なので、空のオブジェクトというものをSceneに配置し、スクリプトをくっつける。
UIの追加
Scene上にCanvasを追加する。
HierarchyでCanvasの配下にTextがあり、GAME CLEARなどの文字列を設定する。
Hierarchy上でCanvas配下にButtonを追加し、RETRYの文字列を設定する。
ゲームクリアの処理
ブロックが全部消えたらゲームオーバーという文字を表示する。
ブロックが全部消えたか判断するため、配列変数にブロックを格納しておき、
GameManagerのUpdate関数で毎フレーム毎にブロック全消えか判定する。
全消え状態だったら、GAME CLEARというUIを表示する。
ゲームクリア処理が延々と継続するのを防ぐため、ゲームクリア済みか判定し、済みだったら何もしない。
public class GameManager : MonoBehaviour
{
public Block[] blocks;
public GameObject uiGameOver;
public GameObject uiGameClear;
private bool isGameClear = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (isGameClear != true)
{
if (IsAllBlockDestroy())
{
Debug.Log("ゲームクリア");
uiGameClear.SetActive(true);
isGameClear = true;
}
}
}
private bool IsAllBlockDestroy()
{
foreach (Block b in blocks)
{
if (b != null)
{
return false;
}
}
return true;
}
ゲームオーバーの処理
ボールが後ろの壁に当たったら、ゲームオーバーとする。
後ろの壁に当たったかの判定は、後ろの壁にタグをつけて、ボールがぶつかった相手がそのタグを持つかで行う。
当たった場合、ボールを消して、ゲームオーバー処理を呼び出す。 …①
GAME OVERのUI画面を表示する。 …②
①はボールのスクリプトにOnCollisionEnter関数として追記する。
②はゲームマネージャーでUI画面をアクティブに変更して表示させる。
public class Ball : MonoBehaviour
~略~
private void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag == "Finish")
{
Destroy(this.gameObject);
myManager.GameOver();
}
}
public class GameManager : MonoBehaviour
~略~
public void GameOver()
{
Debug.Log("ゲームオーバー");
uiGameOver.SetActive(true);
}
ゲームリトライの処理
ゲームクリアまたはゲームオーバー画面のリトライボタンを押したら、シーンをロードすることにより、最初の状態に戻す。
ボタンのインスペクターのOn Clickの項目で、押下時に呼び出す関数を指定する。
using UnityEngine.SceneManagement;の記述が必要。
UnityのFile>Build Setting>Scenes In Buildで、Scene/SampleSceneを追加する。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
~略~
public void GameRetry()
{
SceneManager.LoadScene("Scenes/SampleScene");
}
}
*1:transform.forward + transform.right) * speed, ForceMode.VelocityChange);
}
~略~
プレーヤーの動き
プレーヤーは左右の矢印キーを押したら、左右に動かすだけ。
スクリプトは下記の通り。
public class Player : MonoBehaviour
{
public float speed = 1.0f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if(Input.GetKey(KeyCode.LeftArrow