Unityでのクラスのインスタンス化についてのあれこれメモ

概要

自分でクラスを作ったあと、別クラスから呼び出すときにインスタンス化しないといけない。
この時に、普通のC#みたいに、「newしてインスタンス化する」方法ではなく「unityのインスペクターから、オブジェクトをアタッチする」方法をとらないとうまくいかなかったことがあった。この違いがよくわからないのでちょっと確かめてみる。

実験

2つのサークルを作成。大きいサークルが親。小さいサークルが子オブジェクトになってる。
f:id:mani1414:20220102154424p:plain
f:id:mani1414:20220102152831p:plain

1: Unityのインスペクターからアタッチする場合。

こんなスクリプトを作成。親のサークルにスクリプトをアタッチ
Update関数で子のTestBool関数を呼び出すことで、子の_testFlag変数の論理をチェック。
子の_testFlag変数はFlagTrue()関数を子側のupdate関数で呼び出しまくっているので、trueになるはず。

public class Test : MonoBehaviour
{
    public TestChild testChild;
    bool TestFrag;
    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
         TestFrag=testChild.TestBool();
        Debug.Log("TestFragPrrent " + TestFrag);
    }
}

子のサークルには下スクリプトをアタッチ。

public class TestChild : MonoBehaviour
{
    public bool _testFlag=false;
    // Update is called once per frame
    void Update()
    {
        FlagTrue();
    }
    public bool TestBool()
    {
       return _testFlag;
    }
    private void FlagTrue()
    {
        _testFlag = true;
        Debug.Log("_testFlag " + _testFlag);
    }
}

また、Unity実行前にTestクラスのtestChild変数に、「Unityのインスペクター上から小さいサークルオブジェクトをアタッチする。」
*この動作が「unityのインスペクターから、オブジェクトをアタッチする」方法。
f:id:mani1414:20220102154123p:plain

結果

当然、子側のフラグはtrue。それをチェックしている親側のフラグもtrue。
f:id:mani1414:20220102154559p:plain

2:newしてインスタンス化する方法

親のスクリプトを少し変更。変更点は2点。
・testChildをプライベートにして、インスペクターからアタッチできないようにする。
・Start関数でTestChildをnewしてインスタンス化する。

public class Test : MonoBehaviour
{
    private TestChild testChild;
    bool TestFrag;
    // Start is called before the first frame update
    void Start()
    {
        testChild = new TestChild();
    }

    // Update is called once per frame
    void Update()
    {
        //testChild._testFlag = true;
        TestFrag=testChild.TestBool();
        Debug.Log("TestFragPrrent " + TestFrag);
    }
}

testChildはプライベートなのでインスペクターに現れずアタッチできないようになってる。
f:id:mani1414:20220102155415p:plain

結果

子側のフラグはtrueだが、親側はfalse。親側は子の_testFlag の論理を確認してそれを返すようにしていると思ったのに何で!?ってなった。
f:id:mani1414:20220102155514p:plain

その後いろいろ調べてみて・・・

まだうすーい理解だけども、UnityはMonoBehaviourから継承されているクラスは、起動時に自動でインスタンス化されるというような記事を読んだ。
ってことは、子オブジェクトにアタッチされたスクリプトのクラスは起動時にインスタンス化すでにされており、その後、親オブジェクトでnewしてインスタンス化したとしても、それは子オブジェクトにアタッチされたものとは別のインスタンスってことなんじゃないかと思った。おそらく、「unityのインスペクターから、オブジェクトをアタッチする」という動作は、起動時にすでにインスタンスされたそのものを、呼び出す側のスクリプトに紐づける動作なんじゃないか・・・。

終わり

理解しきれていないが、自分のメモとして残しておく。もしここにたどり着いた方、全く見当違いの可能性もあるので信じないでください。間違っていたら優しく教えていただけたら幸いです。