Unityでのレベルアップシステムの作り方
UnityでRPGなどのゲームを作る場合、敵を倒すと経験値を得て、経験値が一定まで溜まるとレベルが上がるレベルアップシステムはほぼ必須級だ。作り方の一例を紹介していく。
なお、ScriptableObjectとリストについての知識が必要となる。
ScriptableObjectは以前の記事で説明している。作り方など基本的なことがわからない場合は確認してほしい。
ステータス管理
リストについてはこの記事で説明する。
Unityでのレベルアップシステム目次
リストの使い方レベルのデータコンテナを作成
レベルアップシステム作成
レベル表記の変化
目次にもどる
リストの使い方
リストは同じデータ型の変数を複数まとめて扱うことができる変数だ。似たようなものとして配列もある。
配列
リストも配列も変数をまとめる点では同じ。異なるのはリストは変数要素の上限がない点。
例えば、アイテムの一覧を変数に記憶しておく場合は、後からアイテムが増えることを考えると配列よりもリストを使うのが適切だ。今回作るレベルシステムもレベルの上限を変える可能性があるので、リストを使用する。
リストの使い方について紹介していく。
リストの宣言と追加
using System.Collections.Generic;はリストの機能を使うのに必要となるので必ず記述しておこう。
先述したようにリスト自体も変数である。よって以下のように書いて宣言を行っている。
<>の部分は扱う変数の型を示している。変数の型がよくわからない場合は以下の記事へ。
UnityのC#の変数・演算子
今回はstringを指定しているので文字列の変数をリストでまとめることになる。
ItemListの部分がリストの名前である。
続いてItemList.Add("ポーション");としている。
これで文字列がポーションのデータをItemListに加えている。マジックウォーターとロングソードも同様だ。
このように追加した場合、ポーションが0番、マジックウォーターが1番、ロングソードが2番の要素となる。
挿入・取得・更新
以下のように挿入して追加も可能。
先ほどのItemListにこのように追加した場合はポーションが0番、魔法の杖が1番、マジックウォーターが2番、ロングソードが3番の要素となる。
ここから以下のように記述を追加してみよう。
ItemListの2番をaに代入している。よってaに入るのは「マジックウォーター」という文字列である。
以下のように記述すれば要素の更新も可能である。
削除
ItemListから要素を削除する方法もある。数が多いのでまとめて記述する。
まとめて追加
ItemListにまとめて複数要素を追加する方法もある。他のListや配列(Array)が必要。
要素数の確認
ItemListの要素の数を確認したい場合は以下のように書けばいい。
ItemCountにItemListの要素数が代入される。アイテムの所持数に制限をかけたい場合などに役立つ。
要素のインデックス確認
ItemListの指定した値を持つ要素が何番目の要素なのかを取得できる。
ポーションがあったら何番目の要素かをindexに代入する(0から数えて)。なかったら-1が代入される。
要素の存在確認
ItemListの指定した値を持つ要素があるかどうかを判定できる。
xにbool値で返ってくる。ロングソードがあればtrue、ロングソードがなければfalse
他にもソートやFindでの検索などがあるが、別記事で紹介予定。
数が多いので一度に覚えるのは難しい。少しずつ覚えていこう。
目次にもどる
レベルのデータコンテナを作成
ScriptableObjectを使ってデータコンテナを作成する。まずはLvdataと名付けたスクリプトに以下のように記述しよう。以前の記事と基本的な記述は同じ。
ステータス管理
異なるのはpublic List
PlayerExpTableの中ではlevelとexpの変数の宣言をしてある。[System.Serializable]をつけているので、クラスの内容をインスペクターに表示することができる。
最初に[CreateAssetMenu(menuName = "Data/Create LvData")]と記述してある。
よってプロジェクトビューで右クリックし→Data→Create LvDataと選択することで、Lvdataのassetファイルを作成できる。今回はLvdata1と名付けた。
Lvdata1を選択してインスペクター欄を見ると以下のようになっている。+マークを選択することで要素を好きな数だけ増やすことができる。
各要素ではPlayerExpTableの中で宣言したlevelとexpに数値を入れることが可能となっている。今回はレベル5まで要素を作成した上で、以下のように数値を入れてみた。
各要素のレベルになるために必要な経験値を考えてexpに入れてある。
目次にもどる
レベルアップシステム作成
先ほど作ったLvdataを使ってレベルアップシステムを作っていく。敵を倒した時など、経験値が入るタイミングでスクリプトに以下のように記述してほしい。
charadata.EXPにはキャラが持っているEXPの値が入っている(ステータス表示の記事でScriptableObjectで作成したAssetファイルからデータをとってきている)。Kakutokuexpには敵を倒すなどして入ったEXPの値が入っている。
charadata.EXPにKakutokuexp;を足したものをcharadata.EXPに代入。
続いてvar a =Lvdata.playerExpTable[charadata.LV];と記述している。Lvdata.playerExpTableとはLvdataのクラスのplayerExpTableという内部クラスを示す。内部クラスのcharadata.LVの値の要素をvarのaに代入するという意味になる(varは右辺から型を推論させて変数宣言を行え、複雑な型名を書かなくても良くなる)。
先述したように要素は0番から数える。例えば現在はレベル1なのであれば要素1番、つまり2つ目の要素がaに代入されることになる。
そして、if (charadata.EXP >= a.exp)としている。aのExpよりもキャラが持っている経験値のほうが多いか同じならcharadata.LV += 1;としてレベルアップする。
目次にもどる
レベル表記の変化
レベルが上がったら行う表現としてはレベル表記の変化、パーティクルなどを使ってのレベルアップ演出、ステータスなどの上昇など様々だ。演出はお好みで行えばいい。ステータス上昇は別記事で紹介する。レベル表記の変化についてはシステムをテストする目的もかねてこの記事で説明する。
今回は現在のレベルを画面左下に出し、レベルアップすれば更新するようにしていく。
まずはヒエラルキー欄で右クリックしUI→Canvasを選択。名前をUIとしてPlayerの子要素とする。更にUIの子要素としてTextmeshproを作成する(右クリック→UI→Textmeshproを選択)。LVと名付ける。ついでにプレイヤーの名前も表示できるようにしたいので、LVを右クリック→Duplicateで複製して1つ増やし名前をNAMEとする。
Textmeshproに日本語が書けない問題がある場合は以下の記事を確認しよう。
UGUIとは?使い方
LVとNAMEのRext Transformを調整して、画面左下に持ってくる。位置調整方法がわからない場合、以下の記事が参考になる。
メニュー作成
「UI」に以下のスクリプトをアタッチする。
シリアル化しているので、あらかじめインスペクターでcharadataにはAssetファイル、NAMEにはNAMEのゲームオブジェクト、LVにはLVのゲームオブジェクトを指定しておく。
Updateメソッド内に処理を入れており毎フレーム行われる。
キャラの名前をcharanameに代入。キャラのレベルをlvに代入している。
キャラの名前についてはNAME.text = charaname;と記述することで、NAMEのTextmeshproにcharanameの文字列を入れられる。
キャラのレベルについては変数部分は数字だけにせねばならない。
よって、string lvtext = ($"LV{lv}");と記述。$を最初につけ変数部分を{}で囲むことで、文字列に変数を含んだ状態にできる。それをlvtextに代入する。
次にLV.text = lvtext;とすることで文字列をLVのTextmeshproに表示できる。
これまでの処理を行うと以下のような操作が可能である。
敵を倒し経験値を得て、Assetファイルに記述した経験値に達するとレベルアップする。左下のレベル表記が変化する。
続きの記事は以下。
パラメータ管理・表示