GameData クラスは完成しましたので、こちらを利用することによって、
エネミーを倒した際に Exp を加算していく処理と、
その値を外部のスクリプトで取得できるようになりました。
あとはこの処理を
どのスクリプトに記述していくか、という部分を考えていく必要があります。
ここでは
2つの手順に分けて処理を考えてみましょう。
1つは、
エネミーを倒して、Exp を加算するまでの方法です。
もう1つは、
画面に表示されている Exp の値を計算処理が行われるたびに更新を行う方法、以上の、この2つです。
一度にまとめて考えていくのは最初は難しいですので、
処理の実装とおなじで、すべて1つずつ、順番に積み重ねて作っていくことが重要です。
1つ目の
エネミーを倒して、Exp を加算するまでの方法については、
エネミーを倒した際にそのエネミーの情報として持っている Exp を獲得できるとも言えます。
色々な角度から処理の内容を見ていくことが大切です。特定の日本語の処理だけに捕らわれないようにします。
エネミーを倒した際、ですので、これは
EnemyController スクリプトに記述することが最適であると考えられます。
現在エネミーはバレットに接触すると Hp が減算されて、0 以下になったときに破壊されます。
以上のことから、
エネミーが破壊される前に、Exp を加算する処理を記述するイメージを持てばよさそうです。
処理の記述ですが、シングルトンクラスの場合、
変数を用意したり、GetComponent メソッドによる取得処理は不要です。
GameData クラス、そして、その情報が代入されている instance 変数を記述すれば、自動的に、GameData クラスへの参照情報となります。
GameData クラスに用意してあるメソッドはどちらも public 修飾子で宣言してありますので、外部のスクリプトから実行命令を出すことが可能です。
<シングルトンクラスの参照方法>
GameData.instance.UpdateTotalExp("int 型の加算したい値");
int totalExp = GameData.instance.GetTotalExp();
シングルトンクラスは上記のように、「
シングルトンクラス名.シングルトンクラスが代入されている変数」という記述で書くことが出来ます。
今回であれば、
GameData.instance と記述すれば、
GameData クラスにある public 修飾子の情報をそのあとに記述することで命令や参照が行えます。
2つ目の
画面に表示されている Exp の値を計算処理が行われるたびに更新を行う方法については、いくつかの方法が考えられます。
まずは、画面に Exp 表示更新する処理を考えます。何故ならば、これが
この処理のゴール地点(目的)となる処理になるからです。
Exp の表示は画面上の固定情報になります。つまり、
UI ということになりますので、この
UI 情報の制御は UIManager スクリプトに記述をするべきである、と考えることが出来ます。
前回の手順で、画面上に Exp の表示用のゲームオブジェクトは製作済ですので、このゲームオブジェクトの持つ
Textコンポーネント の情報を取得して変数に代入し、
その情報を利用して、
Exp の値を表示更新していく処理を作成すればよいと考えられます。これは
メソッドで用意することが適切です。
何故ならば、エネミーを倒すたびに Exp が加算され、その都度、画面上の Exp の表示更新も処理される、
何度も繰り返し発生する処理になるためです。
繰り返して利用する処理についてはメソッド化して、その中に表示更新の処理を記述することで、同じ処理を何回も書かなくて済むように出来ます。
外部のスクリプトより呼び出される前提のメソッドになりますので、
public 修飾子で宣言するメソッドとして用意します。
目標となる、Exp の表示更新の処理については、どのスクリプトに記述するか目星がつきました。
続いては、この表示更新の処理を行うメソッドを、どのスクリプトから、どのタイミングで呼び出すようにするかを考えます。
ここが非常に難しいので、混乱しないようにします。
ゴール地点となるメソッドを用意したら、次は、スタート地点、つまり、
処理が始まるスクリプトを考えて、そこからゴールまでの道のりを考えます。
ゴールまでの道のりとは、
どのスクリプトを経由して、UIManager スクリプトのメソッドを実行するようにするか、ということになります。
現在までに決まっている処理の流れです。
<ロジックの流れ>
1.Exp を獲得 ← スタート地点
2.【ここを考える】
3.UIManager スクリプトに用意した、Exp の表示更新を行うメソッドを実行する ← ゴール地点
つまり、【2】の部分がゴールまでの道のりになります。このようにイメージを作り、考えていきましょう。
スタート地点は「Expを獲得」ということは、「エネミーが破壊される前」の部分に相当しそうです。
この処理は1つ目の方法で提示したように、EnemyController スクリプトにおいて処理される部分です。
ということは、
スタート地点とは、EnemyController スクリプトになります。
EnemyController スクリプトから処理を実行し、外部のスクリプトを経由して、UIManager スクリプトの処理を実行できるようにする、
これが【2】の部分になります。
EnemyController スクリプトが変数として管理しているスクリプトの情報は、現在は EnemyGenerator スクリプトのみです。
逆に言えば、
EnemyGenerator スクリプトに何かメソッドがあれば、それは EnemyController スクリプトからでも実行できることを意味します。
そしてもう1つ、EnemyGenerator スクリプトで管理している情報に、
GameManager スクリプトがあります。
これを前提に考えます。
現在 UIManager スクリプトの情報を変数として管理しているのは GameManager スクリプトのみです。
ただし、GameManager スクリプトの UIManager スクリプトの情報は
public 修飾子で宣言されている変数ですので、
GameManager スクリプトの情報を利用して、UIManager スクリプトの public 修飾子のメソッドを実行することが可能です。
この手法は以前にも学習している方法です。復習の意味も込めて再度学習を行います。
GameManager スクリプトの情報があれば、UIManager スクリプトの public 修飾子のメソッドが実行できるということは、
GameManager スクリプトの情報を変数として管理している、
EnemyGenerator スクリプトからでも UIManager スクリプトのメソッドを実行することが可能になります。
先ほども書きましたが、EnemyGenerator スクリプトで管理している情報に、GameManager スクリプトがありますね。
EnemyGenerator スクリプトであれば、スタート地点である、EnemyController スクリプトから命令が実行できます。
ここでやっと、処理がつながり、道のりが完成しました。
まとめましょう。
<ロジックの流れ>
1.EnemyController スクリプトにおいて、Exp を獲得 ← スタート地点
2.EnemyController スクリプトにおいて、EnemyGenerator スクリプトに用意したメソッドを実行し、加算後の Exp の値を渡す
3.EnemyGenerator スクリプトにおいて、GameManager スクリプトにある UIManager スクリプトの情報を利用して、Exp の表示更新を行うメソッドを実行する ← ゴール地点
いかがでしょうか。EnemyController スクリプトから処理が始まって、外部のスクリプトである UIManager スクリプトのメソッドを実行する処理が実行できました。
このようにしてロジックを考えていってください。
以前にもお伝えしているように、
ロジックの流れと処理の実装の順番は同じである必要はなく、逆算して実装していった方が問題は少なく済みます。
今回も同じです。最初にロジックで実行する EnemyController スクリプトから EnemyGenerator スクリプトへの処理は、
当然ながら、EnemyGenerator スクリプト側に処理が用意されていなければ実行できません。
そういった部分を考えると、やはり、ゴール地点より処理を実装していく方がよいでしょう。
<実装の順番>
1.UIManager スクリプトを修正して、Exp の値の表示更新を行うメソッドを追加する。
このメソッドを EnemyGenerator スクリプト側から呼び出し、Exp を引数として受け取る。
2.EnemyGenerator スクリプトを修正して、 UIManager スクリプトの Exp の値の表示更新を行うメソッドを呼び出す処理を追加する。
このメソッドを EnemyController スクリプト側から呼び出し、Exp を引数として受け取る。
3.EnemyController スクリプトを修正して、EnemyGenerator スクリプト側に追加した【2】のメソッドを呼び出す。引数としてエネミーの情報の中にある Exp を渡す
イメージをしっかりと作って、処理を実装していきましょう。