【Unity】Unityのクラスのインスタンス化は他のプログラミングとは違う

Unityでクラスのインスタンス化を行うとき、エラーが起きて困ったことはないでしょうか。

私もWeb開発などを行っていてその後にUnityで開発となった時に

クラスのインスタンス化でエラーが出て困惑したことがあります。

今回はUnityでのクラスのインスタンス化について解説していきたいと思います。

目次

Unityのクラスのインスタンス化は他のプログラミングとは違う

コンソールアプリでインスタンス化を確認してみる

Unityのインスタンス化と比較するためにまずは普通のC#のコンソールアプリで確認してみます。

Personクラスがあり、インスタンス化してそれぞれの値をログ出力します。

public class Person
{
    public string Name;
    public int Age;
    public string Prefecture;
    public string Hobby;
}

class Program
{
     static void Main(string[] args)
    {
    // Personクラスのインスタンス化
        Person p1 = new Person();
        Person p2 = new Person();
        Person p3 = new Person();

        p1.Name = "Taro";
        p2.Name = "Jiro";
        p3.Name = "Hanako";

        p1.Age = 25;
        p2.Age = 26;
        p3.Age = 27;

        p1.Prefecture = "Tokyo";
        p2.Prefecture = "Osaka";
        p3.Prefecture = "Nagoya";

        p1.Hobby = "Soccer";
        p2.Hobby = "Baseball";
        p3.Hobby = "Basketball";

        Console.WriteLine(p1.Name + " " + p1.Age + " " + p1.Prefecture + " " + p1.Hobby);
        Console.WriteLine(p2.Name + " " + p2.Age + " " + p2.Prefecture + " " + p2.Hobby);
        Console.WriteLine(p3.Name + " " + p3.Age + " " + p3.Prefecture + " " + p3.Hobby);
   
    }
}

実行結果

クラス変数型の次に変数名を定義し、その後newすることでインスタンスを生成できます。

各々のインスタンスで変数にアクセスし、ログに出力できています。

何ら問題ないと思います。

Unityでのインスタンス化

ではUnityでインスタンス化するとどうなるか見ていきましょう。

ClassAとClassBがあり、ClassAをインスタンス化し、ClassBで使いたいとします。

ClassA.cs

using UnityEngine;

public class ClassA : MonoBehaviour
{
    // この値をClassBで使いたい。
    public int num1 = 120;
    
    void Start()
    {
        
    }

}

【ClassB.cs】

using UnityEngine;

public class ClassB : MonoBehaviour
{
    // ★クラスAのインスタンス化を生成
    ClassA classA = new ClassA();
    void Start()
    {
        // インスタンス化したclassAの変数num1をログ出力
        Debug.Log(classA.num1);
    }

}

ログ出力のため、適当にオブジェクトを作成し、アタッチします。

この状態で再生を押すと下記のような警告が出ます。

You are trying to create a MonoBehaviour using the 'new' keyword.
This is not allowed. MonoBehaviours can only be added using AddComponent().
Alternatively, your script can inherit from ScriptableObject or no base class at all
UnityEngine.MonoBehaviour:.ctor ()

上記の意味は

newをしてMonoBehaviourを作成しようとしています。これは禁止されています。

MonoBehavioursは、AddComponent()を使用してのみ追加できます。

別の方法として、スクリプトは ScriptableObject を継承するか、基本クラスを継承しないこともできます。

という意味です。

色々と書かれていますが、

つまりMonoBehaviourを継承したクラスをインスタンス化するのは禁止されている

ということです。

普通のプログラミングだとインスタンス化のため、newしますが、

UnityではMonoBehaviourを継承したクラスはインスタンス化が禁止されています。

クラス型変数とprivateを使ってみる

「インスタンス化できないのならクラス型変数を使ってprivateにして値を受け渡そう

privateにすると他のクラスからアクセスできないので安全だ。」

ではやってみましょう。

【ClassB】

using UnityEngine;

public class ClassB : MonoBehaviour
{
    // クラス型変数を用紙し、privateで他のクラスからのアクセスを制限
    private ClassA classA;
    void Start()
    {
        Debug.Log(classA.num1);
    }

}

こちらで再生を押すと次のようになります。

NullReferenceExceptionエラーが出ます。どうしてでしょうか。

それはクラス型の変数、classAに値が入っていないからです。

クラスを利用するにはインスタンス化を必ず行う必要があります。

クラス型の変数を定義しただけでは値を利用することができないのです。

ではMonoBehaviourを継承したクラスではどのようにインスタンス化できるのでしょうか。

エディタからアタッチすることでインスタンス化できる

下記のようにコードを変更しましょう。

using UnityEngine;

public class ClassB : MonoBehaviour
{
  // ★SerializeField属性を付与
    [SerializeField] private ClassA classA;
    void Start()
    {
        Debug.Log(classA.num1);
    }

}

SerializeField属性を付与することでエディタで変数の値を確認できるようになります

属性を付与した変数がクラス型であった場合、そのクラスのスクリプトがアタッチされている

オブジェクトをアタッチすることでインスタンス化を行うことができます。

何言ってんだお前、ってなるので画像で確認しましょう。

上記のように修正してインスペクタを見ると画像のようになります。

今の状態では利用したいClassAがアタッチされているオブジェクトがないので

新たにオブジェクトを作成し、ClassAをアタッチします。

今回はClassAObjectを作成し、ClassAスクリプトをアタッチしました。

では、CubeオブジェクトにClassAObjectをアタッチしてみます。

こちらで再生を押すと、変数の値がログに出力されます。

今回は120と値を入れていたので「120」と表示されます。

つまり、UnityでMonoBehaviourを継承したクラスは

クラス型の変数を用意し、SerializeField属性を付与し、

エディタからスクリプトをアタッチすることでインスタンス化することができます

まとめ

いかがだったでしょうか。

Unityでのインスタンス化は他のプログラミングとは違うことが分かったと思います。

クラス型の変数を用意し、SerializeField属性を付与し、

エディタからスクリプトをアタッチすることでインスタンス化することができる

のがUnityの特徴だと覚えてもらうと良いと思います。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

電気制御設計→ITエンジニア
前職は電気系のエンジニアで物流倉庫などの設備を動かしていました。
現在はITエンジニアとして開発に従事。
業務では主にUnity、C#、.NETを利用。
UnityとC#を用いて業務用スマホアプリを完成。
現在、AWS、TypeScript、Nodeの案件に参画中。

コメント

コメントする

目次