kuront’s blog

主にUnityでのゲーム制作やってます。

【Unity】RPG制作 その11- アイテム使用処理(探索中)


 RPG制作その4とその5でアイテムのUIと所持数の処理は実装したのですが、実際に使う処理をまだ実装していないので、今回はアイテム使用処理を実装していきます。
今回かなり煩雑な内容になっています。参考程度に御覧ください。

 現在のゲームの場面に応じて処理が分けられるように、GameManagerでGAMEPHASEという名前で列挙型定数を宣言します。

 


クリックで展開

 そして、探索の開始時(街から探索に出た時)、戦闘に突入した時、戦闘が終わって探索に戻る時、探索が終わって街に戻る時にgamePhaseを変更します。


 


クリックで展開

 


クリックで展開


 


クリックで展開



 


クリックで展開

 それからアイテムの個別の効果を設定するItemDataスクリプトenum STATUSCONDITIONとPlayerManagerのenum STATUSCONDITIONを共用したいので、どちらもGeneralEnum型に宣言し直します。

 


クリックで展開

 PlayerManagerとItemDataのもともとSTATUSCONDITIONだった部分の前にGeneralEnum.をつけて置き換えます。
これでSTATUSCONDITIONをスクリプト間で共有できるようになりました。

 それでは今からアイテムの使用処理の実装をしていきます。今回は探索中に回復アイテムが使用できるようにしていきます。
 ItemUIのアイテムの項目をタップした時に、使用するターゲットを選択する為のパネルと、アイテム使用時にテキストを表示するためのパネルを作成します。ItemUICanvasの階層下にPanelオブジェクトを2つ作成し、それぞれ名前をItemUsePanel,UseItemMessageとします。そしてスクリプト、”ItemUsePanel”を新規作成し、ItemUsePanelオブジェクトに貼り付けます。

f:id:kuront:20210928052726p:plain

ItemUsePanel.csを開き、以下のように記述します。

 


クリックで展開

リストの作り方はItemUIと同じで、項目の生成個数をGameManagerのint型変数のPartyMemberCountの数にしています。現在はPlayer一人だけなので個数を1にしています。パネルの下に生成したゲームオブジェクトにItemEventクラス(今回新規作成するクラス)をAddComponentし、ItemEventクラスの関数をonclickに登録しています。

新規作成したitemEvent.csの中身はこんな感じです。

 


クリックで展開

 このItemEventクラスには、ItemUIの項目がタップされた時に実行されるSetItemTargetPanelと、ItemUsePanelの項目がタップされた時に実行される(回復アイテムの場合は)UseHealItemを定義しています。UseHealItemは先程のItemUsePanelの項目のonclickで実装しました。次はItemUIの項目のonclickにSetItemTargetPanelを登録します。ItemUI.csのSetItemUI関数の以下の部分で記述します。

 


クリックで展開

 これでitemUIのアイテムの項目が押された時にアイテムの使用者を選択するパネルが表示され、実際にそのパネルで対象を選ぶ(今回はPlayerのみですが)と、実際にアイテムの効果を使用対象に及ぼすことができるようになりました。

youtu.be

ついでにデバッグ用のUIも作成しておきました。
今回は以上です。

【Unity】RPG制作 その10- プレイヤーステータスUI作成

 今回はプレイヤーのステータスを表示するUIを作成していきたいと思います。
前回作成した能力成長表のキャンバスをコピーして名前をPlayerStatusUICanvasにします。このCanvasの階層下にあるGrowlistをStatusListに改名し、ExpListの方は削除します。ステータスUIのレイアウトは下の写真のようにしました。

f:id:kuront:20210922174215p:plain

f:id:kuront:20210922174225p:plain

 このUIを制御するスクリプトPlayerStatusUIを新規作成し、以下のように記述します。

 


クリックで展開

 このスクリプトをPlayerStatusUICanvasに貼り付けます。このUIを表示する際にプレイヤーの能力を参照してテキスト出力するようにしています。
 このUIを呼び出せるように、StageUICanvasに新しくButtonを作成します。

f:id:kuront:20210922175759p:plain

 このボタンを押したときの処理を実装したいので、PlayerStatusUIManagerの関数とは別に、StageUIManegerの方でも関数を作成します。

 


クリックで展開

 新しくstatusButtonを制御できるようにしました。StatusButtonを押した時にStageUIManagerのPushStatusButton関数と、PlayerStatusUIManagerのShowStatusUI関数を実行するように、StatusButtonのButtonコンポーネントのOnclickに関数を登録します。それから、CancelButtonを押した時にStatusUIを閉じるように、CancelButtonのOnClickにHideStatuUI関数を登録します。

f:id:kuront:20210922182227p:plain

これでステータスUIを呼び出せるようになりました。
今回は以上です。

【Unity】RPG制作 その9- プレイヤーのステータス成長処理

 前回はプレイヤー死亡時の処理と戦闘終了時の経験値とお金の入手処理を実装しました。今回はプレイヤーの能力経験値が一定値溜まった時にプレイヤー能力を上げる処理を実装していきます。
 最初に、ステータスのデータを扱いやすくするために、能力の項目を列挙型で宣言しておきます。

 


クリックで展開

更にステータスを上昇させる際に使用する一時変数のDictionary型を宣言します。

 


クリックで展開

 このstatusUpCountには能力ごとに能力値を1上げる回数を格納します。(Exp100につき能力を1上昇させる)その回数を調べてリストに格納する関数と初期化関数,、実際にプレイヤーの能力を上げる関数を次のように定義します。

 


クリックで展開

 とりあえずこの関数を戦闘終了後に呼び出します。

 


クリックで展開

 これで経験値が一定値貯まったらプレイヤーのステータスを上げる処理が実装できました。ただ、今のままだとステータスが上がったかどうかが目で見て確認できないため、能力値が一つでも上がった場合は、成長がわかるUIを表示するようにします。
 経験値取得表とステータス上昇表を画像のように作成しました。

f:id:kuront:20210921215838p:plain

f:id:kuront:20210922044733p:plain

 戦闘終了時にこれらのUIを表示します。スクリプトを3つ新規作成し、名前をそれぞれExpList,GrowList,Grow_ExpUIManagerとします。ExpList.csを開き以下のように記述します。

 


クリックで展開

 ExpList.csを先ほど作成したUIのExpListに貼り付け、BattleManagerの変数に渡します。このスクリプトでは、戦闘終了時に表示する能力経験値の取得表を表示し、経験値の貯まり具合をゲージで視覚化します。元々の数値から少しづつ経験値加算する表現をMathf.Lerp関数で実装しています。
 次にGrowList.csを次のように記述します。
 

 


クリックで展開

 このスクリプトを"GrowList"ゲームオブジェクトに渡します。このスクリプトは能力が上昇した際に表示する能力のもとの値と増加した値を、能力ごとにテキストに書き表すものです。
それぞれコルーチンのWaitUntil関数を使ってマウスクリック(あるいはタッチ)したら表を閉じるようにしています。
 そしてGrow_ExpUIManager.csを次のように記述します。

 


クリックで展開

 このスクリプトでは、ExpListとGrowListの表示非表示の制御を行います。
 以上のスクリプトを制作したら、BattleManageで以下のように処理を実装します。


 


クリックで展開

BattleManagerのEndBattle関数を以下のように記述します。

 


クリックで展開

 経験値表と能力上昇表をコルーチンを使って表示します。能力上昇表は能力が一つでも上昇した場合のみ表示します。

実際にテストするとこんな感じです。

youtu.be

今回は以上です。

【Unity】RPG制作 その8- プレイヤー死亡時処理、戦闘勝利時処理(経験値、お金)

 前回は戦闘時のプレイヤーと敵の行動順の処理を実装しました。今回はプレイヤー死亡時の処理と、戦闘勝利時の処理を実装していきたいと思います。
BattleManagerを開き、以下の部分を修正します。

 


クリックで展開

PlayerDeathはプレイヤーがやられた時に呼び出される関数です。この関数をIEnumeratoで定義し、プレーヤーのHPが0になった時に呼び出すようにします。questManager.GotoTown()は単に"Town"シーンに遷移する関数です。

 


クリックで展開

 EnemyTurn関数で敵の攻撃の処理を終えた後にplayer.hp<0かどうかを判定し、trueであればPlayerDeathコルーチンを開始します。
 次は経験値とお金の実装をします。新規でGameManager.csを作成し、ヒエラルキーに同名のゲームオブジェクトを作成して、GameManager.csを貼り付けます。GameManager.csを作成し、次のように記述します。

 


クリックで展開

 ゲームオブジェクトをシングルトンにして全てのシーンで共有できるようにします。中身は今は単にお金を保持するのみです。
それからプレイヤーの情報もシーンが変わっても保持するようにしたいので、PlayerManager.csの先頭に以下の記述をしてシングルトンにしておきます。

 


クリックで展開

 次にバトル中に獲得したお金や能力経験値を一時的に保持しておくスクリプトを作成します。BattkeResultスクリプトを新規作成し、次のように記述します。

 


クリックで展開

戦闘開始時にこのクラスのコンストラクタで初期化し、敵撃破時にAddGainGoldとAddGainExpを呼び出します。

 


クリックで展開

 


クリックで展開

 更に、戦闘が終了した時に、battleResultが保持していた能力経験値とゴールドをPlayerManagerの能力経験値とゴールドに加算します。

 


クリックで展開

これで戦闘で得たお金と経験値を入手する処理が完成しました。

f:id:kuront:20210920191148p:plain

今回はここまでです。

【Unity】RPG制作 その7-戦闘時の行動順の処理 他バグ修正

 前回は戦闘時に敵を複数出現させる処理を実装しました。今回はプレイヤーと敵が速さ順に行動するように処理を実装していきたいと思います。
その前に、現状敵を撃破した時にの演出で、敵の画像と一緒に敵のUIも一緒に拡大するようになってしまっているため、修正します。
 EnemyManagerに以下の記述を追加します。

[Header("敵の画像")]public SpriteRenderer enemyImage; //敵の画像  

 次に敵のプレハブを開き、一番上の階層のGameObjectのSpriteRendererコンポーネントを削除し、そのGameObjectの階層下に空のGameObjectを作成し、名前をImageにします。ImageにSpriteRendererコンポーネントを追加し、SpriteRendererのSpriteに表示させる敵画像を割り当てます。最後に、"Image"オブジェクトを、プレハブの最上位のオブジェクトのEnemyManagerコンポーネントのEnemyImageに割り当てて、プレハブを保存します。

f:id:kuront:20210915112307p:plain

f:id:kuront:20210915142550p:plain


 ついでに、BoxCollider2Dの判定の大きさが画像に対してかなり大きかったので画像に合わせておきました。もともと敵をタップした時にindexの割当がうまくいってないかのような挙動をしていたのですが、これで修正できました。

f:id:kuront:20210915142803p:plain

次にBattleManager.csを開き、以下の部分を変更します。

 


クリックで展開

デバッグ用のメッセージ表示も一緒にしまっていますがご容赦ください。EnemyDeath関数内の死亡時の演出(1秒かけてサイズを2倍に、色をだんだん赤くする処理)を敵のImageのみに適用するようにします。enemysList[enemyIndex].enemyImage.transform.DOScaleで敵画像のみサイズを変え、enemysList[enemyIndex].enemyImage.DOColorで敵画像のみ色を変えられます。UIのサイズは変わりません。

 バグの修正を終えたら、次は戦闘時の行動順の処理を実装していきたいと思います。前回の記事では中途半端に処理を書いてしまっていたので、戦闘時の挙動がバグだらけなので、それが正常に動くようにします。BattleManegerの以下の部分を修正します。

 


クリックで展開

 この関数はプレイヤーと敵の行動順を計算する関数です。この書き方だと、敵が1体、2体の場合はenemysList[2](Dictionary)の範囲外アクセスになってしまいます。3体の場合でも敵を1体倒した後に
その倒した敵のenemyListにアクセスしようとするとエラーになります。なので、enemyListにアクセスする前にenemysList.ContainsKey(index)で指定したindexのKeyが存在するかを判定し、存在した場合のみenemysListにアクセスするようにします。
 修正したものが以下になります。

 


クリックで展開

 ついでに速さのDictionaryに格納する際に、バトラーの速さ+-30%~30%するようにしました。
この関数をBattleManager.csのTurnProcess関数の中で呼び出します。

 


クリックで展開

 TurnProcess関数の一番最初にCalcAttackOrder関数を呼び出し、行動順リストを作成し、その後while(true)でループ処理をさせます。ループ処理内で、ReadAgiDic関数で行動順リストの速さが一番大きいValueのKeyのindexを読み込み、actionIndexに格納します。actionIndexで処理を分岐させ、StartPlayerAttackもしくはEnemyTurnのコルーチンを開始します。それぞれのコルーチンには、呼び出しの際、頭にyield return を付けるようにしました。これでこのコルーチンの処理が終わるまでTurnProcess側の処理を待機させられるようになります(StartPlayerattackとTurnProcessが並列処理にならなくなる)。
 StartAttack関数、もしくはEnemyTurnのコルーチンが終了したら、DeleatAgiDicMaxElem関数で処理をしたactionIndexのKeyの要素をAgiDicから削除します。前回の記事ではこの関数は引数をとらず、ReadAgiDic関数と同じように、AgiDic内のvalueが最大値のKeyの削除を行っていたのですが、それだとバグを発生させる可能性があるかもしれないと思い、actionIndexを引数に持たせて、DeleatAgiDicMaxElem(int key)関数内でAgiDic.Remove(key)としています。これでプレイヤーと敵が速さ順に行動するようになりました。

youtu.be

次回は戦闘勝利時、死亡時の処理を実装していきたいと思います。

【Unity】RPG制作 その6-敵を複数出現させる。

 現在敵は1体のみで出現しますが、今回はそれを複数出現できるように処理を実装していきます。

敵のステータスを表示するUIは敵のプレハブが子オブジェクトとして保持するようにします。

f:id:kuront:20210905121147p:plain

ゲームオブジェクト「QuestManager」の階層下に空のオブジェクト「EnemyGroupList」を作成します。同名のスクリプトを新規作成し、EnemyGroupListに貼り付けます。更に空のオブジェクト「EnemyGroup0」を作成します。そして、syクリプト「EnemyGroup」を新規作成し、オブジェクト「EnemyGroup0」に貼り付けます。

EnemyGroup.csを開いて次のように編集します。


クリックで展開

公開した配列に敵のプレハブを突っ込みます。これが1回の先頭に同時に出現する敵の組み合わせになります。

f:id:kuront:20210905125453p:plain

EnemyGroupList.csを開いて以下のように編集します。


クリックで展開

 先程プレハブにしたEnemyGroupをEnemyGroupListの配列にいれます。この配列が探索時において遭遇する敵のグループのリストになります。

敵と遭遇する処理はQuestManagerに記述しているのでそちらを編集していきます。


クリックで展開

 進むボタンを押したときに20%の確率で敵と遭遇するように変更しました。一応同時に出現する敵の数は3体までにしようと思っているので、EncountEnemyメソッドの中で敵の数で場合分けして敵を出現させるようにしています。ついでにPlayerが死んだときの処理も付け加えておきました。

 次に戦闘を開始した後の処理を書いていきます。BattleManagerを開いて次のように記述します。


クリックで展開

 敵を複数出現させるために敵の情報にindexを追加して番号で管理するようにしています。それからプレイヤーと敵の行動が素早い順で行動できるように素早さを管理するDictinaryを用意しています。上記のスクリプトではまだ正常に動作しないのですが、敵を複数出現させることはできました。

f:id:kuront:20210910153314p:plain

f:id:kuront:20210910162541p:plain

次回は行動順が正常になるように調整していきます。

【Unity】RPG制作 その5-アイテムのUI作成

 今回はアイテムのUIを作成していきたいと思います。

 アイテムのリストを作るのにScreenViewを使います。ScreenViewの階層下にあるContentsに、所持数が1以上のアイテム名のTextコンポーネントを保持したゲームオブジェクトを追加していきます。

 ヒエラルキーに新しくCanvasを作成し、名前をItemUICanvasにします。ItemUICanvasの階層下に「UI」→「ScrollView」を作成。ItemUICanvasのSortOrderを3に設定。ScrollViewはColorを適当に変更し、ScrollRectコンポーネントのMovementTypeをClampedに変更し、HorizontalScrollbarをNoneに変更。そしてScrollView階層下のScrollbarHorizontalを削除します。

 新規に空のオブジェクトを作成し、ItemUISystemを作成。新しくItemUIスクリプトを作成してオブジェクト「ItemUISystem」に貼り付けます。コードは以下のようにします。


クリックで展開

 publicにしたItemManagerとItemCanvasにそれぞれオブジェクト「ItemManager」とオブジェクト「ItemUICanvas」を貼り付けます。スクリプトの実行内容としては、ItemManagerの全てのアイテムの所持数をチェックして、所持数が1以上のアイテムを ItemUICanvasのScrollViewにアイコン付きのテキストで追加するものです。後で使用時の処理を実装できるようにButtonコンポーネントと新しく作成したItemEventコンポーネントもつけています。

 実行すると以下のようになります。

f:id:kuront:20210901104607p:plain


 このアイテムのUIをアイテムボタンを押したときに呼び出すようにしたいので、探索時のUIにItemButtonとBackButtonを追加します。

f:id:kuront:20210901104619p:plain

 StageUIManagerにアイテムボタンと戻るボタンが押されたときの処理を追加します。


クリックで展開

 ItemButtonのOnclickに、ItemUISystemオブジェクトのItemUI.ShowItemUI関数とStageUIManagerオブジェクトのStageUIManager.PushItemButton関数を指定します。
 BuckButtonのOnClickには、ItemUISystemオブジェクトのItemUI.DeleteItemUI関数とStageUIManagerオブジェクトのStageUIManager.PushCanvasButton関数を指定します。
これでアイテムボタンを押せばItemUIを表示し、戻るボタンを押せばItemUIを閉じることが出来るようになりました。

次回からは戦闘時の処理を実装していきたいと思います。