i-school - レベル機能の実装
 前回までの手順で実装したリザルトによる Exp の獲得処理と、ExpTable の機能を利用し、レベルアップ機能を実装します

 具体的な動作しては、バトルにおいてエネミーを倒して Exp を取得してステージに遷移した際に、トータルの Exp の値がレベルアップに必要な ExpTable の値を超えているか判定し、
必要値を超えている場合にはレベルアップする機能を実装します。これは1回のバトルで複数回分レベルアップする Exp を獲得している場合にも対応するように設計を行います


<実装動画>
動画ファイルへのリンク

 この機能が実装できたら、さらに、追加のエフェクトを生成する機能を考えて実装してみることに挑戦しましょう。


<実装動画>
動画ファイルへのリンク

 なお今回の実装は、あくまでもレベルの値が上がっていくだけのものです。
レベルアップに応じて、何か別の処理を行っていることはありません。それはまた別の機能になりますので、処理としては区別して考えるようにしてください。



設計


 複数の機能を活用することにより、レベルアップの機能を設計して実装することが出来るようになります。

 プログラムは複数の小さな設計を組み立てて、より大きな機能を作り出すことができます。
それは同時に、小さな設計が間違えていたり、予期しない動きをするようなときには、より大きな機能は設計できないことも意味します

 処理全体を広く考えて、その上で、範囲を小さくして設計を組み立てていきます。
すぐに習得は難しいですが、常に視野を広く持ち、処理のつながり、機能を考えてロジックを組んでいくことを意識してみてください



 今回は、リザルト機能、ExpTable の機能を利用して、レベルアップの機能を実装します。

 レベルアップの機能は、機能だけではなく、見た目の演出も必要になります。
そのため、まずは最初に演出を考えてから、処理を作っていく段取りにします。

 演出方法は千差万別です。
今回はレベルアップのロゴを利用し、アニメ演出させることで設計していますが、自由に考えて設計してみてください。
完成したら、このエフェクトはプレファブにし、ゲーム内で生成を行います。

 また、ステージのマスク処理の関係上、Canvas ゲームオブジェクトの表示設定によって演出が画面の前面に表示されないため、
新しいエフェクト用の Canvas ゲームオブジェクトを作成しています。

 エフェクト用のゲームオブジェクトは、新しく作成する EffectManager スクリプト内に登録して生成できる状態にします。
このスクリプトはシングルトンクラスとして作成しておくため、いずれのクラスからでも呼び出し命令を受け、
適切なエフェクトの情報を提供できる、管理クラスとしての役割を持たせます。

 最後に Stage スクリプトを修正し、OnEnable メソッド内にレベルアップの判定を行う処理を追加します。
新しい変数やメソッドも追加しています。特に今回は再帰処理という処理によって複数回レベルアップを判定できるようにしています。
そちらもしっかりと理解していくように処理の内容を確認してから記述していきましょう。


Stage ゲームオブジェクトの子オブジェクトとして、新しい Canvas_Effect ゲームオブジェクトを作成する


 現在ヒエラルキーにある Canvas ゲームオブジェクトは Render Mode が Screen Space - Camera に設定されているため、
それとは別に、従来の UI を表示する際に利用する Overlay の Canvas ゲームオブジェクトを新しく作成します。
そうすることにより、レベルアップ時のエフェクトなどを画面前面に表示させる役割を持たせます。

 Stage ゲームオブジェクトの子オブジェクトとして Canvas ゲームオブジェクトを作成してください。
そうしないと、バトルシーンに遷移した際に、UI が非表示にならず、画面に残ったままになります。

 名前は Canvas_Effect のように、すでにある Canvas とは別であることがわかるように設定します。


ヒエラルキー画像



インスペクター画像



 CanvasScaler コンポーネントの UI Scale Mode の設定は、現在ある Canvas ゲームオブジェクトの設定と同じにします。
Game ビューの解像度と同じになっているはずですので、修正してください。


 今回は Canvas コンポーネントの Render Mode の違いがあるため、2つの Canvas ゲームオブジェクトを用意して使い分けるようにしています。
Render Mode についてはもう一度調べてみましょう。


レベルアップの演出用のゲームオブジェクトを作成する


 レベルアップのロゴを PNG 画像として作成します。
そちらを Unity へインポートし、それを登録した Image コンポーネントを持つゲームオブジェクトを、先ほど作成した Canvas_Effect ゲームオブジェクトの子オブジェクトとして作成します

 つまり、レベルアップが発生したら、このゲームオブジェクトを Canvas_Effect ゲームオブジェクトの子オブジェクトとして生成する設計とします。


ヒエラルキー画像



インスペクター画像



Scene ビュー画像



 完成したらプレファブにして、ヒエラルキーからは削除しておきます。



EffectManager スクリプトを作成する


 エフェクトを一元管理するためのマネージャークラスを作成し、こちらに、先ほどプレファブにしたレベルアップのロゴのゲームオブジェクトをアサインします。


EffectManager.cs

<= クリックすると開きます



EffectManager ゲームオブジェクトを作成し、EffectManager スクリプトをアタッチして設定を行う


 Stage ゲームオブジェクトの子オブジェクトではなく、ヒエラルキーに単体のゲームオブジェクトとして作成します。


ヒエラルキー画像




EffectManager ゲームオブジェクトの子オブジェクトとして EffectConteiner ゲームオブジェクトを作成する


 EffectManager ゲームオブジェクトの上で右クリックをしてメニューを開き、Create Empty を選択します。
EffectManager ゲームオブジェクトの子オブジェクトとして新しいゲームオブジェクトが作成されますので、名前を EffectConteiner に変更します。
 

ヒエラルキー画像



インスペクター画像


今はまだ利用しませんが、今後、エフェクトなどを生成した際に、生成元であるゲームオブジェクトが破壊されてしまうようなケースにおいて利用します。


EffectManager ゲームオブジェクトに EffectManager スクリプトをアタッチして設定を行う


 EffectManager スクリプトを EffectManager ゲームオブジェクトにドラッグアンドドロップしてアタッチします。
インスペクターを確認し、2つの変数に情報をアサインしてください。

 エフェクトは、先ほど作成したレベルアップのロゴのゲームオブジェクトのプレファブです。

 もう1つは、EffectManager ゲームオブジェクトの子オブジェクトである EffectConteiner ゲームオブジェクトです。


インスペクター画像



 以上で設定は完了です。


Stage スクリプトを修正する


 バトル後に、獲得した Exp を ExpTableSO スクリプタブル・オブジェクト内のデータと比較して、レベルがアップするかを判定します。
獲得している Exp が多い場合、1回のレベルアップ判定では足りない場合がありますので、再帰処理を利用して、レベルアップが発生しなくなるまで処理を繰り返すロジックを実装します。

 再帰処理とは、広くプログラムで利用される処理です。Unity や C# だけに限ったものではありません。

 メソッドの中で同じメソッドの呼び出しを実行することにより、類似の処理を繰り返すことができます。
今回の場合は、レベルアップの判定するメソッドの中で、再度、レベルアップの判定をするメソッドを実行し、再帰処理を行っています。
こうすることで、レベルアップの判定を1回し、そこでレベルアップしたら、再度、レベルアップの判定を行うようできます。
これをレベルアップごとに確認し、レベルアップがないときにはじめて再帰処理を抜けだすようにしていますので、複数回レベルアップをまとめて判定できるようにしています。

 詳細な記事も多くありますので、処理の理解も含めて調べておくといいでしょう。

 また、UIManager スクリプトに用意したレベルと Exp の更新用のメソッドを呼び出す命令を実装します。
そのため、前の手順で UIManager スクリプトの Start メソッドに記述したデバッグ用の処理はすべてコメントアウトしてください。


Stage.cs

<= クリックすると開きます



ゲームを実行して動作する


 バトルシーンにてエネミーを倒して Exp を獲得後、ステージシーンへ遷移した際、レベルアップに必要な Exp を超えている場合に
レベルアップの処理とロゴのアニメ演出が生成されて実行されれば制御成功です。

 複数回のレベルアップの場合にも同じ挙動になるかを確認してください。
エネミーの Exp を増やしてもいいですし、レベルアップに必要な ExpTable を調整してもいいでしょう。
 
 なお、1回のバトルで獲得した Exp によって複数回レベルアップが発生していても、レベルアップのロゴ演出は1回だけになるよう制御を行っています
レベルアップの処理は再帰処理でおこなっていますので、こちらを確認し、処理の内容を理解しておきましょう。


<実装動画>
動画ファイルへのリンク


<考えてみよう!> レベルアップのエフェクトの実装


 動画のようなエフェクトを追加してましょう。

 エフェクト自体は無料アセットのものを利用して構いません。

 パーティクルをエフェクトを表示する場合、画面の優先順位の問題がありますので、パーティクル内にある SortingLayer の設定や Layer の設定、
エフェクト用のカメラを用意するなど、色々な手法があります。

 まずは、エフェクト用のゲームオブジェクトをステージシーンの中央に配置してみてください。
その状態でエフェクトが見えないのであれば、改善する方法を検討する必要があります。

 色々と調べて、実装に挑戦してみてください。

 エフェクトを生成する際には、EffectManager クラスに変数を用意してエフェクトのプレファブを登録しておくと利用しやすいです。
生成するタイミングは Stage スクリプト内にヒント用の TODO を記述してありますのでご活用ください。


<実装動画>
動画ファイルへのリンク