渋谷ほととぎす通信

「Unityをわかりやすく」初心者のためのゲーム作りブログ

【Unity】Prefabを生成する方法徹底解説

【Unity】Prefabを生成する方法徹底解説

こんにちは、Unityエンジニアのオオバです。

お悩みさん
お悩みさん
  • Prefabって作ってみたけどその後どうすればよいかわからない
  • Prefabから生成する方法がわからない
  • オオバ
    オオバ
    本記事ではこれらの悩みを解決します。

    Prefab(プレハブ)とは 再利用可能なGameObject です。
    再利用してこそ価値を発揮するもの。

    でもPrefabって少し分かりづらいですよね。
    そこで本記事ではUnity初心者向けに、
    簡単なプログラミングを使ったPrefabの生成方法について解説します。

    作成したPrefabを再利用してゲーム開発に生かしていきましょう。

    👇そもそもPrefabって何?という方はこちらの記事をどうぞ。

    PrefabはInstantiateメソッドで生成する

    はじめに結論を簡単にまとめます。

    PrefabはInstantiateメソッドで生成する

    ①Prefabには3種の取得経路がある

    ②PrefabはInstantiateメソッドで生成

    ③Instantiate忘れに注意

    ④生成後のPrefabは通常のGameObjectと同じ

    生成したPrefabはシーン上に配置したGameObjectと何も変わりません。
    普通にAwakeやStartが呼ばれ、Destroyで削除もできます。

    初心者にありがちなのがInstantiateの忘れでハマること。
    この辺含めPrefabの生成方法について解説していきます。

    👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!

    Prefab3種の取得経路

    PrefabからGameObjectを生成するためには、
    Prefabを取得しないといけません。

    その経路は3つあります。

    1. 直接参照
    2. Resources経由
    3. AssetBundle経由

    本記事ではもっともよく使う 「1. 直接参照」 について解説します。

    Prefabの直接参照で取得

    Prefabの直接参照とは、コンポーネントに対して事前に シリアライズ しておくことを指します。

    シリアライズとは言い換えると 参照の保存

    【Unity】Prefabを生成する方法徹底解説_0

    図にするとこんなイメージ。
    Prefabがコンポーネントに参照が保存されている状態です。
    コンポーネント側からPrefabを操作することができる のです。

    プログラムに置き換えるとこうなります。

    💻ソースコード : Prefabをシリアライズするサンプルコード
    using UnityEngine;  
    
    public class MyComponent : MonoBehaviour  
    {
        [SerializeField] GameObject prefab_A;  
        [SerializeField] GameObject prefab_B;  
        [SerializeField] GameObject prefab_C;  
    }
    

    MyComponent.cs というスクリプトファイルを作成して、
    GameObjectにセットしましょう。

    【Unity】Prefabを生成する方法徹底解説_1

    このようにGameObjectにMyComponentをセットできたら、
    インスペクタにPrefabをセットするエリアができましたね。

    【Unity】Prefabを生成する方法徹底解説_2

    👆このエリアに生成したいPrefabをセットするのです。

    【Unity】Prefabを生成する方法徹底解説_3

    このような感じでプロジェクトウィンドウからドラッグ・アンド・ドロップします。

    これで準備完了です。

    Instantiateで取得したPrefabの生成

    Prefabの生成には Instantiateメソッド を使います。
    最初にサンプルコードを見てみましょう。

    using UnityEngine;  
    
    public class MyComponent : MonoBehaviour  
    {
        [SerializeField] GameObject prefab_A;  
        [SerializeField] GameObject prefab_B;  
        [SerializeField] GameObject prefab_C;  
    
        private void Start()  
        {
            // prefab_Aを生成  
            Instantiate(prefab_A);  
        }
    }
    

    Startメソッドで prefab_A を生成しています。
    Instantiateメソッドは引数にprefabをセットすることで、
    そのPrefabを生成することができるのです。

    ではUnityを実行してみましょう。

    【Unity】Prefabを生成する方法徹底解説_4

    ヒエラルキーに Prefab_A(Clone) という名前のGameObjectが作成されましたね。

    このようにPrefabの生成には Instantiate メソッドを使うのです。

    【よくある間違い】Instantiate忘れ

    初心者によくある間違いなのですが、
    PrefabをInstantiateせずにそのまま使ってしまうミス です。

    【間違い】Prefabの親を変更する
    private void Start()  
    {
        // 【間違い】prefab_Aの親をヒエラルキーのオブジェクトに指定する  
        prefab_A.transform.SetParent(transform);  
    }
    

    このコードを実行すると、以下のようなエラーが出力されます。

    Setting the parent of a transform which resides in a Prefab Asset is disabled to prevent data corruption

    エラー内容は、Prefabアセット(Prefab)をヒエラルキー上のオブジェクトを親階層にすることは禁止されているとのこと。

    正しくは以下のコードです。

    private void Start()  
    {
        // prefab_Aを生成してアクセスする  
        var obj = Instantiate(prefab_A);  
        obj.transform.SetParent(transform);  
    }
    

    prefab_AをInstantiateで生成して、親階層を変更する。

    大事なのは 「Prefabをそのまま使うことはない」 ということです。
    Instantiate で生成してから使うということを覚えておきましょう。

    Prefabには「Prefab」と名付けよう

    プログラム上でPrefabか、そうでないかを見分けるのは難しいです。
    例えば以下のようなコードです。

    [SerializeField] GameObject _gameObject1;  
    // 実はPrefab  
    [SerializeField] GameObject _gameObject2;  
    

    _gameObject1、_gameObject2はともにGameObject型。
    実は _gameObject2はPrefab。

    しかしプログラム上ではそれを判別することはできません。

    解決策として 変数名に「Prefab」 をつけること。

    [SerializeField] GameObject _gameObject1;  
    // 実はPrefab  
    [SerializeField] GameObject _gameObjectPrefab;  
    

    このように「Prefab」を名前に加えることで、かなりのミスを防げます。

    ぜひPrefabを直接参照する場合は、
    「Prefab」というキーワードを付けた変数名にしてみましょう。

    生成後のPrefabは通常のGameObjectと同じ

    Instantiate で生成したPrefabは、
    シーン上に配置したGameObjectと何が違うのでしょうか。

    結論、違いはありません。同じように扱われます。

    • Awake
    • Start
    • Update

    このようなUnity定義メソッドも同じように実行されます。
    Destroyで自由に削除も可能です。

    つまりPrefabだからといって何かが違うわけではありません。
    生成された後は、ほかのGameObjectと同じように扱えるわけです。

    まとめ : Prefabを生成する方法まとめ

    最後に記事の内容を簡単にまとめます。

    Prefabを生成する方法まとめ

    ①Prefabには3種の取得経路がある

    ②PrefabはInstantiateメソッドで生成

    ③Instantiate忘れに注意

    ④生成後のPrefabは通常のGameObjectと同じ

    Prefabを生成することで、
    事前に作成しておいたGameObjectを再利用できます。

    これこそPrefabの真骨頂。
    Unity開発でヘビーユースされる機能なのです。

    Prefabを使うことでチーム開発はより円滑に進められます。
    すべてのオブジェクトをシーンに置くと作業しづらいですよね。
    シーンは同時に編集できません から。

    そこでオブジェクトを Prefab化 しておくのです。

    Unity実行中にPrefabを生成。
    そうすることでほかメンバーと作業が競合しません。

    ぜひPrefabの正しい生成を理解し、
    円滑なUnity開発に生かしてもらえればと思います。

    この記事があなたのゲームづくりに役立つとうれしいです。

    「Unity初心者大学」というUnity初心者向けのYouTube始めました!!
    ぜひチャンネル登録をお願いします!

    最後まで読んでいただきありがとうございました!
    すばらしいUnityライフをお過ごしください。

    オススメ記事
    検証環境
    • Unity2020.3.26f1