今回は途中で何度か Start メソッドを別のメソッドに作り変えて、外部のスクリプトから呼び出して実行する処理に変更しました。
現在のスクリプトを確認してもらうと分かりますが、
Start メソッドが記述されているのは GameManager スクリプトただ1つです。
見直してみてください。
これはどういうことかというと、ゲームを実行した際に最初に実行される Start メソッドが1つだけ存在していることになりますので、
常に、
この GameManager スクリプトの Start メソッドからゲームの処理が開始される、ということになります。つまり、そういった設計を
意図して作っています。
複数のスクリプトに Start メソッドが記述されている場合、Unity では、どのスクリプトの Start メソッドを実行する、という保証がありません。
例えば、A 〜 D までの4つのスクリプトにそれぞれ Start メソッドがあった場合、最初にゲームを実行した際には A のスクリプトの Start メソッドが実行されたものの、
次にゲームを実行した際には C のスクリプトの Start メソッドが実行された、というように、
Start メソッドを実行するタイミングは同じであっても
処理される順番が完全に Unity 側に依存した処理になります。そのため、
こちらが考えている順番通りに毎回 Start メソッドが実行されることはありません。
これを、すべてのスクリプトを見た時に、B のスクリプトにだけ Start メソッドがあったとしたら、いかがでしょうか。
1つしかないので、必ず、
この Start メソッドが一番に実行されることが確定されます。
そしてこれは設計を行う際に検討しておくことで、こういった処理になるように、こちらで考えながら作り上げていくことが出来ます。
Start メソッドが1つだけ、という状態を作りだすことが出来れば、常にゲームを実行した際にはこの Start メソッドから処理が開始されることになります。
そのため、
自分が考えた順番で Start メソッド内に処理を記述することで、必ずその順番で処理が実行されることも確定されます。
現在の GameManager スクリプトの Start メソッドを確認してみてください。
<GameManager スクリプトの Startメソッド>
void Start()
{
// ゲーム終了の判定を、「ゲームが終了していない」状態にする
SwitchGameUp(false);
// DefenseBase スクリプトに用意した、DefenseBase の設定を行うための SetUpDefenseBase メソッドを呼び出す。引数として GameManager の情報を渡す
defenseBase.SetUpDefenseBase(this);
// PlayerController スクリプトに用意した、PlayerController の設定を行うための SetUpPlayer メソッドを呼び出す。引数として GameManager の情報を渡す
playerController.SetUpPlayer(this);
// EnemyGeneratorの初期設定
enemyGenerator.SetUpEnemyGenerator(this);
// TransformHelper スクリプトの temporaryObjectContainerTran 変数に情報を渡す
TransformHelper.SetTemporaryObjectContainerTran(temporaryObjectContainerTran);
// GameClearSet ゲームオブジェクトを見えない状態にする
uiManager.HideGameClearSet();
// GameOverSet ゲームオブジェクトを見えない状態にする
uiManager.HideGameOverSet();
}
いかがでしょうか。現在までに作成してあるすべてのスクリプトに対して、1つずつ順番に処理が実行されていることが分かります。
そのため、この順番に処理が実行されていくことが確定していますので、複数の Start メソッドがあったときのように、
どの処理が先に実行されるか、そういった心配は全くありません。
自分のイメージ通りの処理が実際に処理されていることになります。
こういった設計にして処理を記述できる利点は、こちらが考えた処理通りに実行されていくという以外にもいくつかあります。
1つは
エラーを発見しやすくなる、ということです。
例えば、enemyGenerator.SetUpEnemyGenerator(this); というメソッドが実行された際にエラーが出たとします。
その場合、この処理以前の処理はすべて問題なく動いていることが判明します。
何故ならば、途中で処理が止まることがなかったのでこのメソッドまで実行された、ということが確定しているからです。
つまり、このメソッド以前の処理に問題がない、ということがわかれば問題の切り分けが出来ていますので、エラーの原因となる場所の特定が容易になります。
もう1つは、
処理の順番を組み立てやすくなる、ということです。
ゲームを実行すると Start メソッドの順番通りに処理が動いていく、ということは
処理が終了した時点の情報を確認しながら、どの処理の後にこの処理を入れたい、というイメージがわきやすく、
実際に記述する際にも、記述する対象となる場所の把握が容易になります。
例えば、PlayerControler の SetUpPlayer メソッドが実行されて、必要な情報が設定されてから
その設定した情報を利用した処理を記述したい、という場合であれば、このSetUpPlayer メソッドよりも下に処理を追加すれば
自分が意図している順番通りに処理が動く、ということが分かります。
とはいえ、最初からこのように設計が行えるわけではありません。
ですが、かといって、
考えずにいてはいつまでたってもこういった設計方法を構築することが出来ません。
少しずつ、処理の内容を理解しながら、処理全体の流れを確認して、どうしたら上手く処理を設計できるのか、
そういう意識を常に持ってロジックを考えていくようにしてください。
学習時間は非常にかかりますが、
ロジックの構築や設計を行うことがエンジニアの仕事になりますので、
毎日の学習を、こういった点に意識を向けて繰り返し行うことによって、着実に自分のスキルとして培っていきましょう。