Unity では コンポーネントの間で Awake()
や Start()
などの呼び出し順序が保証されていません.そのため次のような問題が発生します.
例として,class A はメンバクラスとして class B を持ち,class B はメンバクラスとして class C を持っているとします.クラスの構造を簡単に表すと次のようになります.
A
└ B
└ C
そして,各クラスは次のように定義されているとします.
class A : MonoBehaviour{
B m_b;
void Awake(){
var m_b = GetComponent<B>() as B;
}
void Start(){
m_b.Hello();
// do somethings
}
}
class B : MonoBehaviour{
C m_c;
void Awake(){
var m_c = GetComponent<C>() as C;
}
public void Hello(){
m_c.Hello();
// do somethings
}
}
class C : MonoBehaviour{
String m_str;
void Start(){
m_str = "Hello World!";
}
public void Hello(){
Debug.Log(m_str);
}
}
ここで,A::Start()
で表示されるものが何かということが問題になります.考えられるのは次の2つです.
C::Start()
がA::Start()
よりも先に実行された場合 :"Hello World!"
C::Start()
がA::Start()
よりも後に実行された場合 :""
(コンパイラによっては null エラー)
対処法は次のものが考えられます.
m_str = "Hello World!";
をC::Awake()
で実行する.C::Hello()
を呼び出す時にC::Start()
が呼び出されているかチェックする.つまり,次のように C を設定します.
class C : MonoBehaviour{
String m_str;
bool m_isStarted = false;
void Start(){
m_str = "Hello World!";
m_isStarted = true;
}
public void Hello(){
if(!m_isStarted){
Start();
}
Debug.Log(m_str);
}
}
コメント