PrefabをInstantiateし、ブロックをスクリプトで出現させる方法

Unity

Unityでブロック崩しのゲームを作成したので、アウトプットも兼ねてブロックをスクリプトから並べる方法を記載していきます。筆者はUnity初心者ですが、色々ググりながらUnityroomに1本ゲームを出せましたので、そのノウハウを記載していく次第です\(^o^)/

参考にさせて頂いた記事 

【Unity】スクリプトからブロック崩し用のPrefabを配置するサンプル
ブロック崩しのように大量のオブジェクトを配置する必要のあるゲームでは、手動でオブジェクトを配置していくのは大変です。スクリプトとPrefabを使えばボタンひとつでオブジェクトを配置してくれるようになってかなり便利。なので、このサンプルを試し

環境

エディション Windows11Home
バージョン 22H2

非効率な例:手作業で並べていく

まず初心者にありがちなブロックを並べる手段の1つとしてはゲームオブジェクトを1つず作り複製し手作業で並べていく方法です。プログラムやゲームエンジンに慣れていない方は、スクリプトからオブジェクトを配置していくという発想に至らないかもしれません。筆者もそうでした。

このように1つ1つを並べていては、高さや列の幅を調整していくだけで日が暮れそうになります。規模が大きくなれば尚更ですね。後述する方法を使えば、今後かなり楽にオブジェクトは配置できるようになりますし、ゲームの幅も広がるでしょう。

スクリプトからオブジェクトを配置する方法

さて本題のスクリプトからオブジェクトを配置する方法です。スクリプトでオブジェクトを配置する方法としてはInstantiateを使用します。

Instantiateとは


スクリプトからオブジェクトを生成
生成したオブジェクトの位置を指定
生成したオブジェクトの回転や向き、角度を指定

などの働きを持つメソッドです。実際にUnityのGame画面でInstantiateを使用した1連の動きを見ていきましょう。


このように何もない空間からオブジェクトを生成することができます。これは、アクションゲームで何もないところから「プレイヤーにヒットすればHPが減る」というようなトラップを生成したりすることに応用できます。またパズルゲームでは新規ブロックを生成するということにも役立ちます。

Plane(床)とCubeを作成

実際にUnityを動かしましょう。
まずはヒエラルキービューを左クリックし、3DObject→PlaneとCubeを作りましょう。

Plane(床)のスケールはそれぞれ自分で調整してもらえればOKです。ここでは以下のように設定しました。またGame画面で見やすいようにMeinCameraのPositionも以下のように設定します。

CubeのPrefab化

Cubeオブジェクトを作成したらPrefab化させます。Prefabとは、生成したオブジェクトのコピーのことです。今後、1つ1つオブジェクトを手作業で生成なくてもPrefab化したオブジェクトを使用することによって、好きなタイミングで好きな量を出現させることができます。

まずProjectビューのAssetsフォルダにPrefabフォルダを作成しましょう。作成したら、Prefabフォルダの中に画像のようにCubeオブジェクトをドラッグ&ドロップします。その後、ヒエラルキビューのCubeオブジェクトは削除してしまいましょう。

・・・

ちょっと待ってください!!ヒエラルキビューからCubeオブジェクトを削除してしまったら画面から肝心のオブジェクトが消えてしまうじゃないですか。Unity初心者の皆さん安心してください。後からしっかり生成されます。

Scriptの作成

Assetsフォルダ内にScriptフォルダを作成しScriptフォルダ内で右クリックしCreate>C#Scriptを選択しましょう。ファイル名とクラス名を同じにしなければならないことに注意してください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PrefabSample : MonoBehaviour
{
    //生成されるPrefabオブジェクトへの参照を保持する
    public GameObject PrefabObj;
    //Prefabオブジェクトの親オブジェクトへの参照を保持する
    public Transform ParentObj;
    //Prefabを生成する高さを定義する
    public float Height;


    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        //フレームカウントが50の倍数時にPrefabを生成する
        if(Time.frameCount % 50 == 0)
        {
            CreateCube();
        }
    }

    void CreateCube()
    {
        //ローカル変数ObjにInstantiateで生成(実体化)するオブジェクトの情報を代入する
        GameObject obj = Instantiate(PrefabObj,Vector3.zero,Quaternion.identity);
        //オブジェクトが生成される位置を再定義
        obj.transform.localPosition = new Vector3(0f,Height,0f);
        //TransformクラスのSetParentメソッドで親オブジェクトを設定する。
        obj.transform.SetParent(ParentObj);

    }
}

上から順に私なりに解説させて頂きます。

変数の宣言


まずはフィールド変数を3つ上から順に記述していきます。全てpublic変数とします。public変数とすることで後からインスペクター上で値を設定できたり、Prefabオブジェクトをドラッグ&ドロップで代入することができます。

①GameObject型の変数、PrefabObjは先程Prefab化したCubeオブジェクトの情報を保持するために宣言します。
②Transform型の変数、ParentObjはPrefabオブジェクトの親オブジェクトを設定するために宣言します。
③Float型の変数、HeightはPrefabを生成する高さを定義しています。この記事では生成するPrefab(Cubeオブジェクト)を上から降らせるようにするため高さを設定しています。自分のゲームの用途にあわせて変数やメソッドを変更しても良いかと思います。

②で親オブジェクトへの参照を保持する変数を宣言する理由が初心者の方にはわかりにくいと思います。後に説明するのですが、ヒエラルキービューで空(から)のゲームオブジェクトを作成します。なぜ空(から)なのかというと今回は空(そら)からCubeが降ってくるような演出にするため視覚に映るようなオブジェクトはいらないのです。

他にも空(から)のゲームオブジェクトを作成するメリットや理由はいくつかあります。こちらの記事が分かりやすかったので参照してみてください。

【Unity 簡単解説】create emptyの使い方をマスターしよう
どうも、ナッツパパです(^^)本記事では、Unityの【Create Empty】の使い方について解説していきます。上画像のように【Create Empty】は、Unityメニューバーの左から4番目GameObjectのプルダウンメニューか

PrefabSampleクラス内でCreateCubeメソッドを定義します。そしたらUpdateメソッド内でCreateCubeメソッドをフレームカウントが50の倍数時に呼び出します。

Instantiateでオブジェクトの情報を入れていく

Instantiateメソッドでオブジェクト情報を代入していきます。
1つ目としてPrefab化するオブジェクトの情報を入れます。ここでは先程、宣言したPrefabObj変数になります。
2つ目は生成したオブジェクトの位置を決めます。ここでは座標(0,0,0)を表すVector3.zeroの情報を入れます。
3つ目は回転の指定です。Quaternion.identity(クォータニオン)は少し説明するのが難しいですがこの場合だと回転をしていないのと同じということになります。

localPositionを設定する

この3つをローカル変数objに代入していきます。続いてobj.transform.localPositionでオブジェクトが生成される位置を定義(代入)していきます。ここでHeightをpublicで定義していたことによってインスペクタービューで自在に値を変えることができます。

Instantiateの引数でVctor3.zeroとありますが、そこをHeightの値に変えればいいんじゃない??と思いますが、transform.localPositionに代入することに意味があります。localPosition(ローカルポジション)とは、「親の Transform オブジェクトから見た相対的な位置」ということです。

transformについてはこの記事を参考にしたら理解がすすみました。

【Unity】transformを使いこなす!座標・回転など自在に操作しよう! | 侍エンジニアブログ
この記事では「【Unity】transformを使いこなす!座標・回転など自在に操作しよう!」といった内容について、誰でも理解できるように解説します。この記事を読めば、あなたの悩みが解決するだけじゃなく、新たな気付きも発見できることでしょう。お悩みの方はぜひご一読ください。

SetParentメソッドで親オブジェクトを設定する

最後にtransformクラスのSetParentメソッドで親オブジェクトを設定します。Cubeオブジェクトはヒエラルキビューから消去しているため、ヒエラルキビューで親子関係を設定することができません。このメソッドを使用すればスクリプトから親子関係を設定することができます。

Scriptをアタッチするための空(から)のゲームオブジェクトを生成する

スクリプトは完成しました。スクリプトをアタッチさせるためのオブジェクトを作成していきます。ヒエラルキビューで右クリックしCreateEmptyをクリックすると空(から)のゲームオブジェクトが生成されます。

空(から)のゲームオブジェクトの名前はCubeParentにします。CubeParentに先程作成したスクリプトをアタッチしていきます。アタッチしたスクリプトに先程publicで宣言したフィールド変数の中身をセットできるようになっています。


PrefabObjにはPrefab化したCubeオブジェクトをセットしましょう。
ParentObjにはCubeParentオブジェクトをヒエラルキビューからドラッグ&ドロップでセットしましょう。これでCubeParentオブジェクトを親オブジェクトとして設定することとなります。
Hightには好みで実験的に数字をいれてみましょう。ここでは100に設定しました。

重力の設定

Componentウィンドウ→Physics→RigidbodyからRigidbodyをPrefab化したCubeオブジェクトに追加しましょう。Use Gravityにチェックを入れ重力がかかるようにしましょう。

Cubeの色やバウンドする挙動を追加

プロジェクトビューのAssetsフォルダ内にMaterialフォルダを追加します。右クリック→Create→Materialを選択するとMaterialを作成できます。Materialは材料みたいなものです。カラーだけ選択できればOKです。

これはおまけなのですが、バウンドの挙動を追加してみます。同じくプロジェクトビューで右クリックしCreate→PhysicMaterialを選択します。

PhySicMaterialはこのように設定します。これでCubeオブジェクトがバウンドするようになります。
あとはこのMaterialを画像のようにCubeオブジェクトにセットしていくだけです。

これで全ての設定がおわりました。あとはゲームプレイボタンを押すのみです。Cubeが何もないところから生成され重力の影響を受けて床に落ち、バウンドするでしょう。

おわりに

InstantiateやPrefab化、SetParentメソッドはゲーム開発をしていく上で、よく使う技術になるかと思いますのでぜひ覚えていきましょう!!最後まで読んでくれた方ありがとうございました。このサイトの整備も進めて参りたいと思います(_ _)

コメント

タイトルとURLをコピーしました