Unityでゲームのクエストを管理する機能とページUIを作成する

最近のゲームではクエストと呼ばれる小さなイベントがありそれをこなしていくという機能が多くなりましたね。

ゲームをコンプリートしようという気持ちが強い人は全クエストをこなしたくなるものです。

(^_^)v

そこで今回はUnityでクエスト管理をする機能を作成してみようと思います。

クエストはステータス画面を開いた時に表示されるようにし、

クエスト画面ではクエストが終了したもの、してないものが一発でわかるようにしたり、タイトルやその内容を表示するようにします。

全クエストが100個あった場合等は全部のクエストをクエスト画面に表示すると大変なので数を決めて表示し、前のページ、次のページに遷移出来るようにボタンを配置します。

非常にシンプルに作成してはいますが、内容的にはボリュームが多いです。

それぞれの関連性を丁寧に見ていってください(あいかわらず説明は下手です)。

スポンサーリンク

クエストを管理するゲームオブジェクトとUIの作成

まずはクエスト画面を構成するゲームオブジェクトと個々のクエストの内容を表示するUIを作成していきます。

ヒエラルキー上で右クリック→Create Emptyで空オブジェクトを作成し、名前をQuestManagementとします。

その子要素に右クリック→UI→Canvasを選択し名前をQuestUIとします。

その子要素にUI→Panelを選択し名前をBackgroundとします。

Backgroundの子要素にはUI→Panelを選択し名前をQuest0とします。

Quest0の子要素にUI→Panelを2つ作り、名前をTitlePanel、InformationPanelとします。

TitlePanelの子要素にUI→Toggle、InformationPanelの子要素にUI→Textを作ります。

Toggleを選択しトグルの設定を変更します。

トグルの設定を変えて変更出来ないようにする

↑のようにInteractableのチェックを外し、TransitionをNoneにします。

これで手動でチェックボックスを操作する事が出来なくなります。

Quest0を選択した状態でCtrl+Dでコピーを4つ作成し、最後の番号を増やした名前にします。

最後にページ移動ボタン領域を作成します。

Backgroundの子要素にUI→Panelを選択し名前をButtonPanelとします。

その子要素にUI→Buttonを2つ作成し名前をPrevとNextにします。

PrevとNextの子要素にはTextがあるので表示されるテキストをPrevとNextに変更しておきます。

クエスト関連ヒエラルキー

↑が作成したクエスト関連のヒエラルキーになります。

Quest1~Quest4まではQuest0をコピーして名前の最後の数字を変えただけで同じです。

これでクエスト関連のゲームオブジェクトは出来ました。

BackgroundゲームオブジェクトのインスペクタでAdd Component→Layout→Vertical Layout Groupを設定します。

これでQuest0~Quest4、ButtonPanelのパネルが縦に並ぶようになります。

Vertical Layout Groupを追加し子要素を縦に並べる

↑のようにコンポーネントを追加しました。

最終的に出来たクエストの確認画面は

クエスト画面

↑のようになっています。Questの子要素のLabelのテキストで初期タイトル、Informationのテキストで初期内容を設定出来ます(後でスクリプトで操作するので特に意味はありませんが・・・)。

クエスト情報を保存するQuestクラスを作成する

クエストはそれぞれ情報を持っています。

名前や内容、どうすればクリア出来るか?といった情報です。

これらはクエスト用のクラスを作成しそこに情報を保持出来るようにし、クエストを管理するスクリプトからアクセスして個別のクエスト情報を得られるようにしましょう。

今回はクエストの名前と内容を保持出来るようにします。

Questスクリプトをクラスの形で作成します。

Questクラスは単純にインスタンス化した時にタイトルと内容を保持し、それを返す関数が定義されているだけです。

C#でQuestクラスを作成する時はMonobehaviourクラスを継承している部分を削除するかObjectクラスを継承して作成する必要があります。

このQuestクラスはゲームオブジェクトに取り付けて使用するものではなく他のスクリプトからこのクラスのインスタンスを生成し使用するものです。

クエストを管理するQuestManagementスクリプトを作成する

個々のクエストクラスは出来ましたが、そのクエストクラスからインスタンスを生成し全クエストを管理するようなスクリプトが必要です。

その為QuestManagementゲームオブジェクトに新しくQuestManagementスクリプトを作成し取りつけます。

クエストはこのQuestManagementスクリプトで全て生成します。

クエストが完了しているかどうかもこのスクリプトで管理する為、クエスト数分のboolean型の配列を用意しています。

今回はそれぞれのクエストを細かく作るのが大変なのでfor文を使ってクエストクラスを大量生産してます・・・(^_^;)

今回のクエスト画面はQキーを押したら開き、再度押したら閉じるという単純なものにしました。

実際にQuest0~Quest4にそれぞれのクエストの情報を入れているのはShowQuestスクリプトになり、こちらは後で作成します。

引数で指定している数値は何ページ目を開くかの数字です。

スクリプトでは0を渡しているのでクエストの最初のページが開きます。

QuestManagementで全クエストのリストを保持しているので、それに関する値を得られるようにゲッターを用意しています。

例えばクエストの0番目が終了しているかどうかはIsQuestFlag(0)と呼び出すわけですね。

クエスト情報を表示するShowQuestスクリプトを作成する

クエストのUIを見て頂くとわかりますが、1度に表示するクエストは5個です。

そこでクエスト画面を開いた時は最初の5個を表示し、Nextボタンを押したら次の5個を表示、というようにしなければいけません。

そこでBackgroundゲームオブジェクトに新しくShowQuestスクリプトを作り取りつけます。

ShowQuestスクリプトでは現在開いているページをnowPage変数で保持出来るようにし、そのページを使ってQuest0~Quest4のUIに表示するクエストの内容を変更します。

OnEnable関数はこのスクリプトが設定されているゲームオブジェクトがアクティブになった時に呼ばれるので、クエスト画面が開いた時に実行されます。

クエスト画面が開いた時は常に最初のページを表示させる為、ここでnowPageを0に初期化しています。

Show関数では1ページに表示するクエストの個数を表すnum数分繰り返し、クエストの情報をテキストに表示しています。

このnumに設定する数値は作成したクエスト個別のUIの数と一致させます。

このスクリプトのゲームオブジェクトの子要素の数からButtonPanelの分を引いて表示するクエスト数とします。

今回の場合はQuest0~Quest4の5つを作成したのでnumに5が入ります。

Show関数を細かく見てみましょう。

引数として受け取るのは何ページ目か?という情報です。

表示するクエスト情報分のTransform配列を確保します。

pageNum(ページ情報)にnum(1ページで表示するクエストの個数)をかけ、i番目を足すと全クエストからの番号を得られます。

そのクエスト番号を使ってクエストのタイトルとクエストの内容情報を取得し一時変数に入れます。

QuestManagementスクリプトで管理している『クエストが終了しているかどうか?』のフラグを取得し、ToggleのisOnにその値を入れています。

こうすることでクエストが終了しているものはタイトル横のチェックボックスにチェックが入ります。

それぞれの子要素からテキストUIコンポーネントを取得しそこにさきほど取得した情報を表示します。

1度に表示するクエストは5個ですが全クエストが3しかなかった場合等に残りの2つにも何らかの情報を表示しなければいけません。

その為にクエストの番号と全クエストの数とを比較しクエスト番号が全クエスト数を超えた場合は空文字等を表示するようにしています。

NextPageとPrevPage関数はNextボタンとPrevボタンをそれぞれ押した時に実行する関数です。

次のページや前のページに表示するクエストがない場合は表示しないように制限を加えて表示するようにしています。

クエスト関連の設定を行う

クエスト関連のスクリプトが出来たのでそれぞれ設定していきましょう。

まずはQuestManagementゲームオブジェクトに設定したQuestManagementスクリプトです。

QuestManagementスクリプトの設定

↑のように全クエスト数を50に設定し、Backgroundゲームオブジェクトに設定するShowQuestスクリプトを設定します。

次はBackgroundゲームオブジェクトに設定したShowQuestスクリプトの設定です。

ShowQuestスクリプトの設定

↑のようにQuestManagementスクリプトを設定します。

次にPrevとNextボタンのOn Click()に設定をします。

PrevとNextボタンを押した時に実行する関数

↑のようにPrevボタンのOn Click()のゲームオブジェクトにBackgroundをドラッグ&ドロップし、実行する関数にShowQuestスクリプトのPrevPage関数を指定します。

Nextボタンも同じように設定し実行する関数はNextPage関数にします。

クエスト画面は最初表示されていると困るのでQuestUIゲームオブジェクトのインスペクタのチェックを外しておきます。

クエストが完了するサンプルの作成

クエスト画面の実装は出来ましたが、クエストが完了した時にどうなるのかがわかりません。

そこでそこに行くと設定したクエストが完了する領域を作成します。

クエスト完了領域を3つ作成

↑のようにヒエラルキー上で右クリック→3D Object→Cubeを3つ作成しそれぞれの名前の後にクエストの番号を付けておきます。

この番号は特に使うわけでなくわかりやすいかなと思って付けただけです(スクリプトで使う番号+1になっています)。

Completeスクリプトを作成し取りつける

コライダのIs Triggerにチェックを入れ物理的に当たらないようにします。

CubeそれぞれにはCompleteスクリプトを取りつけQuestManagementスクリプトと自身のクエスト番号をインスペクタで設定します。

↑のように侵入してきたのがPlayerタグを持っており、かつこのクエストが完了していない場合はQuestManagementスクリプトのSetQuestFlag関数を使ってクエストを完了させます。

クエスト完了領域の実際の画面

実際のクエスト完了をさせる領域は↑のようになりました。

クエスト機能を確認する

これでクエスト機能が全て出来ました!

実際にキャラクターを動かしクエストを完了させる領域を周ってクエストを完了した後にクエスト画面を開いて確認してみます。

まずはQキーを押してクエスト画面を開きクエスト一覧が見れる事を確認し、その後クエスト1が完了するエリアに侵入しクエスト画面を開きます。

クエスト1に相当する最初のクエストのチェックが入りました。

次にクエスト10の領域に入りクエスト10にチェックが入っているかどうかを確認し、最後にクエスト2も確認してます。

今回の記事はクエストの管理機能を作ったんですが、それとは別にページ送りのUIも作成出来ましたね。

あ・・・最後に気付いたんですが、クエストUIに表示するものがない時はUI自体を非表示にしてしまえばいいかもしれませんね。

例えばQuest3とQuest4に表示するクエストがなければQuest3とQuest4を非表示にするとか。

ふむ・・・・・(-_-)。

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます

コメント

  1. 匿名 より:

    いつもこのサイトにはお世話になっています。
    いきなりの質問で悪いんですが、スキルツリーの機能は作れますか?

    • こんにちは

      スキルツリーの機能は

      https://gametukurikata.com/program/quest

      のクエストを管理する機能をスキルを管理する機能に応用するといいと思います。

      『攻撃10%UP』というスキルを覚えるには『攻撃5%UP』というスキルを先に覚えなければいけないという制約があれば『攻撃5%UP』スキルを覚えているか?という条件を確認しスキルポイントを使って『攻撃10%UP』が覚えられるようにする。

      というようなスキルを管理するクラスを作成するといいと思います。

      スキルツリーという事で表示するUIが重要になってくると思いますが、一つ一つのスキルをUIのボタンで表現し覚えられるスキルはフォーカス出来るようにし、覚えられないものはフォーカスを出来ないようにするといいかもしれません。

      UIのフォーカスに関しては

      https://gametukurikata.com/program/uifocus

      https://gametukurikata.com/ui/statuswindow

      等を参照してみてください。

      今は余裕がないのでサンプルを作る事が出来ません・・・・(-_-)