Unityのゲーム作りをさくっと解説(3)
久しぶりの更新です……
多忙により前回の更新より少し間が開いてしまいました、すみません。
Unityの初心者向けさくっと解説です。
今回はスクリプトを導入します。
出来ることが大幅に広がり、いよいよゲームらしくなってきます。
コンポーネントの追加
現在、シーン内に機能を持たない玉オブジェクトがぽつんと置かれている状態です。(※厳密にはスプライトを描画する機能だけを持っています)
Unityでは、このオブジェクトにコンポーネントを足して機能を追加します。
物理エンジン関連コンポーネントの追加
HierarkeyウインドウまたはSceneウインドウで玉オブジェクトを選択すると、Inspectorウインドウにコンポーネントが表示されます。
現在の玉オブジェクトには「Transforrm」と「Sprite Renderer」コンポーネントのみがあります。
玉オブジェクトに、コンポーネントを追加します。 InspectorウインドウのAdd Componentボタンよりコンポーネントを追加(アタッチ)出来ます。
ここではPhysics 2Dカテゴリーの「RigidBody 2D」を追加してみます。
動かしてみます。「Play」ボタンを押すとエディタ内で動作します。
玉が落ちていきました。RigidBody 2Dにより、このようにオブジェクトが物理エンジンによる影響を2D空間内で受けるようになります。
次は、玉に「Circle Collider 2D」を、周囲の壁3つに「Box Collider 2D」をアタッチします。
接触判定が行われるようになりました。
プレハブ化
次は玉を大量に生成したいですが、その前に「プレハブ化」を行います。
オブジェクトをプレハブに格納しておくことで、複製が容易になります。
プレハブの作成
上のメニューからAssets -> Create -> Prefab
またはAssetsウインドウで右クリックしてCreate -> Prefabを選択します。
空のプレハブ「New Prefab」がプロジェクト内に作られます。分かりやすいように名前を付けておきます。
Hierarchyウインドウのオブジェクトをプレハブにドラッグアンドドロップすると、オブジェクトの内容がプレハブに格納されます。
また、これまでシーン中にあったオブジェクトはプレハブに関連付けされ、このプレハブのインスタンス(実体)となります。
試しにプレハブをシーン中にドラッグアンドドロップしてみると、プレハブの複製が新しいインスタンスとしてシーン中に配置されるのが分かると思います。
プレハブのインスタンスはHierarchyウインドウ内では青文字となり、Inspectorウインドウでは「Prefab」の項目が表示されます。
例えばシーン中に配置したインスタンスを更新した後にApplyボタンを押すと、プレハブが同じ状態に更新されます。
なお、メニューの「GameObject -> Break Prefab Instance」を選択すると、このオブジェクトとプレハブの関連付けを解除できます。
スクリプト
ここではゲームのシーン全体を管理するスクリプトを追加します。
スクリプトの導入
ここでは空のオブジェクトを作ってスクリプトを置きます。どこに追加するかは迷うところですが、例えばカメラのオブジェクトに追加してもいいと思います。
HierarchyウインドウかGameObjectメニューの「Create Empty」で空のオブジェクトを生成します。
InspectorウインドウのAdd ComponentボタンからNew Scriptを選択すると、新しいスクリプトがAssetsフォルダに追加されると同時にオブジェクトにアタッチされます。
Projectウインドウのスクリプト(歯車のアイコン)をダブルクリックすると、スクリプトエディタが起動します。Windows版のUnity2017の標準的なインストール設定だとVisual Studio 2017 Communityが起動するはずです。(標準的にはMonoDevelopがあります。Visual Studio Codeなどを使用することも出来ます。)
※右上のアカウント情報は伏せてます
スクリプトの編集
C#の解説は少な目です(すみません……他サイト様のC#の解説なども参照願います)
Unityのスクリプトは基本的にはMonoBehaviourクラス ※リファレンス の派生クラスとなります。ここにゲームオブジェクトの振る舞いを実装します。
(画像)
(テキスト)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour {
// フレームのカウンター
private int tCount = 0;
// ピース(現在はボール)
public GameObject peace;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
tCount++;
if (tCount>=30)
{
// 新しくピースを発生させる
Instantiate(peace, new Vector3(1.8f, 5.0f), Quaternion.identity);
// カウントを0に戻す
tCount = 0;
}
}
}
Update()関数は毎フレーム呼び出される関数です。30フレームごとにInstantiate()関数 ※リファレンス を呼び出し、ボールのプレハブのインスタンスを生成します。
メンバ変数のpeaceが初期化されてないように見えますが、これはInspectorで行うためです。 後で気が付きましたが、pieceのスペルを間違ってました
publicの変数はインスタンスが生成されるときに初期化されます。GameObject型の変数にはプレハブやシーン中のオブジェクトを入れられます。ここで先ほど作成したボールのプレハブを指定しましょう。
publicの変数はインスタンスが生成されるときに初期化されます。ここで先ほどのボールが入ったプレハブを指定しましょう。
実行してみます。
上から降り続けるようになりました。
スクリプトの改良
もう少し修正してみます。
- 4色ランダムで降るようにする
- 降ってくる位置をランダムにする
- 降ってくる頻度を変更できるようにする
- シーン中に存在する玉数の上限を決め、一定以上降らないようにする
生成元のプレハブを配列にし、複数の中からランダムで選ばれるようにします。
Random.Range()は乱数を生成する関数です。引数が整数(int)型のときと小数(float)型のときは振る舞いが少し異なります。※リファレンス Random.Range
降ってくる玉の種類を0以上4未満のうちからランダムで選択し、生成するx座標を2.0f以上2.0f以下からランダムで決定します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour {
// フレームのカウンター
private int tCount = 0;
// ピースを一個生成するフレーム数
public int genFrame;
// これまでに生成したピースの数
private int pieceCount = 0;
// ピースの最大生成数
public int pieceCountMax;
// 生成するピースのプレハブ
public GameObject[] piecePrefab;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
tCount++;
if (tCount >= genFrame)
{
if (pieceCount >= pieceCountMax)
{
int pieceColor = Random.Range(0, 4);
float pieceX = Random.Range(-2.0f, 2.0f);
// 新しくピースを発生させる
Instantiate(piecePrefab[pieceColor], new Vector3(0, pieceX), Quaternion.identity);
pieceCount++;
}
// カウントを0に戻す
pieceCount = 0;
}
}
}
色違いのボールのプレハブを3種類用意します。
配列となったGameObject型変数pieceのサイズに4を入力して、プレハブを入れます。他のパラメータにも値を入れましょう。ついでにスペルミスも直しました
実行
非常にそれっぽくなりましたね。 降ってくる最大数のパラメータを変更すると、その通りになるのが確認出来ると思います。
次回予告
次回はユーザーの操作も入れて、よりゲームらしくします。 今度はなるべく早いうちに……