【Unity】MonoBehaviourで禁止されていること

Unity開発では必ずと言っていいほど使うMonoBehaviourクラス。

こちらを用いる際に禁止されていることを紹介したいと思います。

目次

クラスのインスタンス化が禁止されてる

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

新規にスクリプトを作成する際にはデフォルトで

MonoBehaviourクラスが継承された状態でクラスが作成されます。

using UnityEngine;

public class TestSample : MonoBehaviour
{
  // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

しかし、この状態のままインスタンス化しようとすると警告が出ます。

新たにInstanceSampleクラスを作成し、TestSampleクラスをインスタンス化してみます。

using UnityEngine;

public class InstanceSample : MonoBehaviour
{
    TestSample testSample = new TestSample();

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

コチラの状態で保存し、適当なゲームオブジェクトにアタッチしてみましょう。

すると、下記の画像のような警告が出ます。

警告文は以下になります。

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:

new’ キーワードを使って MonoBehaviour を作成しようとしています。
これは許されません。
MonoBehavioursは、AddComponent()を使用してのみ追加できます。
別の方法として、スクリプトは ScriptableObject を継承するか、基本クラスを継承しないこともできます。
UnityEngine.MonoBehaviour.ScriptableObjectを継承することもできます:

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

ちなみに

: MonoBehaviour

を削除するとインスタンス化はできます。

MonoBehaviourを継承していないものはPure C#と呼ばれたりもします。

ただし、Start関数やUpdate関数などUnityで用意されているメソッドが使えなくなります

MonoBehaviourを継承したクラスの値を他のクラスでも使いたいとき

では、他のクラスの値を使いたいときはどうすればよいでしょうか。

下記のコードがあるとします。

TestSample

using UnityEngine;

public class TestSample : MonoBehaviour
{
    // この変数を別のクラスで使いたい
    public int InitialNumber;
}

上記の変数、InitialNumberをInstanceSampleクラスで使いたいとします。

その時はpublicでクラス型変数を用意してエディタでアタッチすると他のクラスの値を使うことができます。

ではInstanceSampleクラスを修正します。

InstanceSample

using UnityEngine;

public class InstanceSample : MonoBehaviour
{
    // publicにしてエディタからアタッチできるようにする
    public TestSample testSample;

    void Start()
    {
        Debug.Log(testSample.InitialNumber);
    }

}

次にエディタ画面でオブジェクトにアタッチします。

こちらで再生を押すと…

MonoBehaviourを継承したクラスでも値の受け渡しができていることを確認できました。

コンストラクタが禁止されている

先ほどのTestSampleのコードでコンストラクタを行ってみましょう。

using UnityEngine;

public class TestSample : MonoBehaviour
{
    public int InitialNumber;
    public TestSample()
    {
        InitialNumber = 5;
        Debug.Log(InitialNumber);
    }
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

}

int型のInitialNumberという変数を用意し、コンストラクタで5を代入して

変数の値をログに出力しているコードです。

こちらで保存し、Cubeにアタッチしてみると以下の画像のようになります。

ゲームを開始していないのにログ出力されました…

この状態でゲームを再生してみると以下のようになります。

上記ではゲームの再生と終了を繰り返しているのですが、ログが再生時と終了時に出力されています

コンストラクタは初期化のメソッドですが、何度も呼び出されていて不自然です。

このことからわかるようにMonoBehaviourを継承したクラスのコンストラクタが禁止されている

ことがわかります。

初期化したい場合はAwakeメソッドStartメソッドを使いましょう。

おわりに

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

本日紹介した2つの点はいずれもMonoBehaviourを継承した場合のルールになります。

他のアプリ開発とは違ってこのようなルールがあるのだと覚えておきましょう。

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

この記事を書いた人

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

コメント

コメントする

目次