【Unity】自作クラスの実装方法

スクリプトで、MonoBehaviourクラスを継承する必要がない場合(例えば、Start()メソッドなどが不要)で、new演算子を使ってインスタンスを作りたい場合の方法です。

MonoBehaviourクラスを継承しているクラスからnew演算子を使ってインスタンスを作ってはいけません
実行するとコンソールに次のように表示され注意が促されます。

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 ()
Player:.ctor ()
GameDirector:Start () (at Assets/GameDirector.cs:9)

翻訳
newキーワードを使用してMonoBehaviourを作成しようとしています。 これは許されません。 MonoBehaviourは、AddComponent()を使用してのみ追加できます。代わりに、スクリプトはScriptableObjectを継承するか、ベースクラスを持たないことができます。
Player:.ctor ()
GameDirector:Start () (at Assets/GameDirector.cs:9)

MonoBehaviourの継承の要/不要について

継承が必要なケース

ゲームオブジェクトにアタッチされたコンポーネントとしてスクリプトを作成する必要がある場合。例えば、そのオブジェクトをコントロールするためにStart()メソッドやUpdate()メソッド、またOnCollision()イベントなどが必要な場合。
トランプのカード情報など、オブジェクトにアタッチすることで機能を持たせる必要がある場合。

継承が不要なケース

Unityエンジンの管理が不要なケースです。
ゲームオブジェクトにアタッチされることを前提としない場合。
Unityエンジンの管理下にないため、コンポーネントとしてゲームオブジェクトにアタッチすることもできません。

サンプルの作成

Unity バージョン

2021.2.5f1

次のようなクラスを作成します

自作のクラス

public class Player
{
    public string name;
    public int hp;
}

自作クラスのインスタンスを作成するクラス

using UnityEngine;

public class GameDirector : MonoBehaviour
{
    Player player;

    void Start()
    {
        player = new Player();
        player.hp = 10;
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log(player.hp);
        }
    }
}

シーンの作成

GameDirectorクラスは、GemaObject(空のオブジェクト)にアタッチします。
Playerクラスは、MonoBehaviourを継承していないためコンポーネントとしてゲームオブジェクトにアタッチすることはできません。

実行

実行後、スペースキーを押すと、Playerクラスのインスタンス(player)のHpフィールド値が表示されます

インスペクターで自作クラスのフィールド値変更ができるようにしたい場合

次のようにクラスを変更します

自作のクラス

インスタンスをインスペクターに表示させたいので、[Serializable]属性をつけてシリアライズ化します。
(本来、インスタンスはメモリ上に展開されているため、テキストのデータとして保持されていません。)

using System;

[Serializable]
public class Player
{
    public string name;
    public int hp;
}

自作クラスのインスタンスを作成するクラス

[SerializeField]属性で、プライベートアクセスの場合でもインスペクターに表示できるようにします。

new 演算子でのインスタンス作成は必要ありません。

using UnityEngine;

public class GameDirector : MonoBehaviour
{
    [SerializeField]
    Player player;

    void Start()
    {
        //player = new Player();
        player.hp = 10;
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log(player.hp);
        }
    }
}

シーンの作成

シーンの構成に変更はありません。
インスペクターで値を調整できるようになりました。

C#,Unity

Posted by hidepon