2014年1月20日月曜日

続:C#クラスのインスタンス化~Unity

UnityのC#スクリプトではクラスのインスタンス化に若干特殊性があるのでメモ。


■同一オブジェクト内の他のスクリプトへアクセス


AクラスからBクラスのメンバを呼び出す場合の例:


【当該オブジェクト内に予めクラスBのスクリプトがUnity画面の操作でドラッグ&ドロップされている場合】

public class A : MonoBehaviour {
    B ptrB;
    void Start(){
        ptrB = GetComponent<B>();
    }
    void Update(){
        ptrB.Func(); //クラスBのインスタンスのメンバ関数Func()へアクセス
    }
}

【当該オブジェクト内に予めクラスBのスクリプトがUnity画面の操作でドラッグ&ドロップされていない場合】


 GetComponent() を AddComponent として、

ptrB = gameObject.AddComponent<B>();

とする。
public class A : MonoBehaviour {
    B ptrB;
    void Start(){
        ptrB = gameObject.AddComponent<B>();
    }
    void Update(){
        ptrB.Func(); //クラスBのインスタンスのメンバ関数Func()へアクセス
    }
}

※gameObjectは当該オブジェクトを指す。
GetComponent()では省略できるのに、なぜかAddComponent()では省略できない。


■他のオブジェクト内のスクリプトへアクセス

まずなんらかの方法で目的の「他のオブジェクト」を特定しなければならない。
特定してそのGameObjectのインスタンスを取得することからはじまる。

ここでは特定方法としてタグを用いてみた。
例として「目的のオブジェクト」に予めUnityのHierarchy~Inspectorからタグ名に「SoundManager」と付けておいた。ただしこのタグ名は全オブジェクトでたった1つにのみ付いているものとする。


【Aクラスからタグ名「SoundManager」が付いたGameObject内のBクラスのメンバを呼び出す場合】

public class A : MonoBehaviour {
    B ptrB;

    void Start(){
        GameObject go = GameObject.FindWithTag("SoundManager"); //タグ検索
        if(go==null){
            return; //タグが見つからなかった場合
        }
        ptrB = go.GetComponent<B>();
        if(ptrB==null){
            return; //クラスBが見つからなかった場合 
        }
    }
    void Update(){
        ptrB.Func(); //タグ"SoundManager"が付いたGameObject内のクラスBのインスタンスのメンバ関数Func()へアクセス 
    }
}

※他のオブジェクト内に予めクラスBのスクリプトがUnity画面の操作でドラッグ&ドロップされている為、GetComponent()で取得できる。つまり実行後、他のオブジェクトがインスタンス化された際に同時に中に含まれるクラスBもひとつインスタンス化されている。


■インスタンスが無いクラスへアクセス

インスタンスが無いクラスへはアクセスできない。
なのでまずは目的クラスのインスタンスを生成する必要がある。その為にまずは器となるGameObjectの生成から行う。

public class A : MonoBehaviour {
    B ptrB;

    void Start(){
         GameObject obj_B = new GameObject("obj_B");//GameObject生成
        ptrB = obj_B.AddComponent<B>(); //クラスBをインスタンス化してGameObject "obj_B"に追加
    }
    void Update(){
        ptrB.Func(); //生成したGameObject "obj_B"内のクラスBのインスタンスのメンバ関数Func()へアクセス 
    }
}

※最初クラスBのスクリプトはどのオブジェクトにも含まれていないのでひとつもインスタンス化されていない。まずGameObjectを生成。それにコンポーネント追加でインスタンス化するところから行う。




もっと簡単な方法では staticにしてしまう方法もある。ただしこの場合は複数インスタンスを生成できないので困る場合がある。



0 件のコメント:

コメントを投稿