2Dのキャラの動かし方をずっといろいろ試していたんだけど、初めて気がついて詰まってしまった点があったので、備忘録として。
「GameManager」というクラスを実装すると同時に、2Dアクションゲームの敵役として「missile_horizonal」というプレハブを用意しておく。
この「missile_horizonal」には同名のスクリプトファイルがAdd Componentされており、プレハブは「GameManager」から動的に生成できるように「Resources」フォルダ内に配置されている。
「GameManager」内で「createMissile」という関数を実行している。ここで動的に「missile_horizonal」のインスタンスを生成し、画面に表示している。
ここで問題になるのが、関数「createMissile」内で「missile_horizonal」内の「init」という関数を実行していることだ。
GameObject missile = (GameObject)Resources.Load ("missile_horizonal");
int dir = Random.Range (0, 2);
//中略
Instantiate (missile, position, Quaternion.identity);
missile_horizonal mh = missile.GetComponent ();
mh.init (dir);
要は変数「dir」の値に応じて挙動を変更したいために、生成したインスタンス内の関数「init」を外部から実行しようとしている。
bool setFlg = false;
//中略
void Update ()
{
if (!setFlg) {
return;
}
//中略
}
//中略
public void init (int dir)
{
Debug.Log ("missile_init");
dirVec = Vector2.left;
if (dir == 1) {
this.transform.Rotate (new Vector3 (0.0f, 180.0f, 0.0f));
}
setFlg = true;
}
関数「init」の中身はこんな感じ。
ここで問題になるのが、変数「setFlg」の中身なのだが、各関数の実行順を見てみると、
- 「missile_horaizonal」内の「Awake」
- 外部から実行される、「missile_horaizonal」内の「Init」
- 「missile_horaizonal」内の「Start」
という順番になっており、どうやらこの「Start」の段階で変数の中身が初期化されてしまうらしい。 つまり関数「init」内でtrueが代入された変数「setFlg」の値が、関数「Start」内で初期化されて再度falseに戻ってしまうようなのだ。
従ってUpdateのreturn文以降の処理はいつまでたっても実行されず。。。。ちょっと予想していない挙動だったので、念のために書き留めておく。