Unityを使った3Dゲームの作り方(かめくめ)ゲーム開発エンジンUnityを使った3Dゲームの制作に参考になる情報を公開しています。2019.12.03今回はユニティちゃんRPGのゲームデータのセーブ、ロード、削除機能を作成していきたいと思います。前回はタイトルシーンの作成をしました。ユニティちゃんのRPGを作ってみよう32ータイトルシーンを作成するーユニティちゃんRPGのタイトルシーンを作成していきます。gametukurikata.com2019.12.02ユニティちゃんのRPGを作ってみようの他の記事はユニティちゃんのRPGを作ってみようユニティちゃんのRPGを徐々に作っていくカテゴリです。gametukurikata.comから見ることが出来ます。今回はゲームのデータを保存し、後からデータをロードしてゲームを再開する機能を作成していきたいと思います。今回の作り方だとUnityエディター上でデータのロードがうまく出来ない事がありました。独自形式のScritableObjectのSkillやItemのインスタンスIDをシリアライズして情報として保存しているからかもしれません。SkillやItem情報はstring型のスキル名やアイテム名でシリアライズしてデータを保持しておいて、データロード時にアイテムデータベースに保持していたScriptableObjectのアセットファイルのスキル名やアイテム名と保存していたスキル名とアイテム名が一致したら再度そのSkillやItem型のデータをUnityChanStatusやYujiStatusのSkillListやItemDictionaryに設定し直すといいかもしれません。スタンドアロン形式だと問題が出なかったんですが、今回の機能の記事は参考程度にしてください。(._.)スポンサーリンクゲームデータのセーブとロードの概要ゲームデータはPlayerPrefsを使ってデータの保存と読み込みをしたいと思います。データはJSON形式で扱います。保存するデータにはキャラクターが持つアイテムのクラスとその数を入れているItemDictioanryのデータを保存する必要がありますが、これをそのままシリアライズしてJSON形式に変換出来ませんでした。通常のC#であればDictionaryをシリアライズする事も可能?みたいでItemDictionaryからDictionaryに変換してやろうと思いましたが、UnityのJsonUtilityクラスの場合は出来ないようなので、ItemDictionaryのキーと値を個別にList、Listとして保持し、それをシリアライズしてデータに保存することにします。データをロードした時はそのキーと値のリストを再度ItemDictionaryに設定するようにします。保存するデータは全て新しくDataクラスを作成し、シリアライズ可能なフィールドに値を設定しそれをJSON形式に変換して保存します。味方キャラクターのステータスはAllyStatusでこれをまとめてシリアライズし、ロードした時にそのままDataクラスのフィールドに設定する事も出来そうですが、AllyStatusはItemDictionaryを持つので、クラスのCloneメソッドを使ってデータをそのままクラスに入れてシリアライズせず、多少面倒ではありますが個別のデータをDataクラスのフィールドに設定していくことにします。PlayerPrefsを使うとWindowsだとレジストリにデータが保存されます。レジストリにデータを保存したくない場合はファイル等にセーブデータを出力するようにするといいかもしれません。Unityでゲームデータのセーブ・ロードを行う方法Unityのゲームで進行具合やキャラクターのステータスをデータとして保存しておき、それらのデータを読みだして続きから再開するというのは必須の機能になっています。その為に今回はゲームデータのセーブとロードが出来るようにしてみたいと思います。gametukurikata.com2016.12.01プラットフォームによって保存先が変わるので、詳しくはUnityのスクリプトリファレンスを確認してください。registry.docs.unity3d.comセーブデータ用のクラスを作成するまずはセーブデータ用のクラスを作成します。Assets/RPG/Scriptsフォルダに新しくDataスクリプトを作成します。}}}どのシーンにいたかのデータ、ワールドマップならその位置と角度のデータ、ユニティちゃんと大鳥ゆうじのステータスを保存するデータのフィールドと単純にそれを返すプロパティを用意しています。List型に個々のキャラクターのステータスデータを一括で保持出来ればいいんですが、最初に記したようにItemDictionaryを使っているので面倒ではありますが個々のキャラクター毎にフィールドとプロパティを用意しています。studioのエディターでpropと入力してその後Tabキーを押すとプロパティのテンプレートが出来るので、黄色い表示の部分をTabキーで移動し書き換えると素早く作成出来ます。プロパティは単純にフィールドの値を返すのと値を設定する事をしているだけです。データのセーブ機能を作成するゲームデータのセーブをする機能を作成していきます。Emptyを選択し、名前をSaveManagerとします。Assets/RPG/Scriptsフォルダに新しくSaveDataScriptスクリプトを作成し、SaveManagerゲームオブジェクトに取り付けます。スクリプトが長いので分割して説明します。クラス定義とフィールドまずはクラス定義とフィールド部分を見ていきます。unityChanTransform;}partyStatus、UnityChanStatus、yujiStatusはそれぞれのステータスファイルを設定します。dataNameはレジストリに記録する時の名前です。この後にセーブデータの番号を不可して3つのデータを作成出来るようにします。saveData1~3はセーブデータの情報を表示するボタンの子要素のTextを設定します。unityChanTransformにはヒエラルキー上のUnityChanを設定し、ワールドマップでのユニティちゃんの位置と角度を取得する時に使用します。保存されているデータを表示する保存されているデータを表示するDisplayDataメソッドを作成します。"データがありません。"データがありません。"データがありません。"データがありません。"データがありません。"データがありません。";}}}}DisplayDataは保存されているデータの簡易データを表示する為のメソッドです。最初にデータを入れるDataクラスのインスタンスを生成します。データをセーブした場所の文字列をplaceに入れます。データは3つ保存できるようにするので、for文を使って3回繰り返します。通常は0から開始されますが、直感的にiは1~3にした方が分かりやすいと思いiを1で初期化しました。{で、まずそのデータがあるかどうかを調べます。データがあればJsonUtility.FromJsonを使って指定した型のインスタンスを生成します。引数で与えるのは読み込むJSON形式のデータなのでPlayerPrefs.GetStringを使って保存したデータを取得しそれを指定しています。PlayerPrefs.GetStringで保存したstring型のデータを取得出来ます。PlayerPrefsに関してはUnityでゲームデータのセーブ・ロードを行う方法Unityのゲームで進行具合やキャラクターのステータスをデータとして保存しておき、それらのデータを読みだして続きから再開するというのは必須の機能になっています。その為に今回はゲームデータのセーブとロードが出来るようにしてみたいと思います。gametukurikata.com2016.12.01を参照してください。DataクラスのインスタンスdataのSceneTypeがFirstVillageであればplaceに最初の村、WorldMapの場合はワールドマップを入れます。SceneTypeはデータを保存した時のシーンに応じて入れるセーブデータです。最後にセーブデータ用のTextに簡易データであるユニティちゃんのレベル、名前、今いる場所を表示します。データがなければデータがありませんと表示します。セーブデータの2と3もやっていることは同じです。Assets/RPG/Scripts/SceneMovementDataスクリプトのSceneTypeにWorldMapを追加します。{StartGame,FirstVillage,FirstVillageToWorldMap,WorldMapToBattle,BattleToWorldMap,WorldMap}データを保存するデータを保存する処理をするSaveメソッドを作成します。JsonUtility.ToJson(data));PlayerPrefs.Save();}最初にDataクラスのインスタンスdataを作成します。SceneManager.GetActiveSceneで現在のシーンを取得しその名前に応じてSceneTypeを入れます。WorldMapの場合はロードした時のユニティちゃんの位置と角度も再現したいので、ユニティちゃんの位置と角度もデータに入れます。後はユニティちゃんや大鳥ゆうじの現在のデータをそのままdataのプロパティにセットしているだけです。ItemDictionaryに関してはキーと値を別のList型に入れ、それをdataのプロパティに入れています。CommandScriptに処理を追加するセーブ関連のUIの操作は以前作成したCommandScriptで操作します。CommandScriptに処理を追加します。́Д`)CommandModeに追加まずはCommandModeにDataPanel、ConfirmationPanelを追加します。CommandMode{CommandPanel,StatusPanelSelectCharacter,StatusPanel,ItemPanelSelectCharacter,ItemPanel,UseItemPanel,UseItemSelectCharacterPanel,UseItemPanelToItemPanel,UseItemPanelToUseItemPanel,UseItemSelectCharacterPanelToUseItemPanel,NoItemPassed,DataPanel,ConfirmationPanel}フィールドを追加フィールドに新しく追加します。saving;dataPanelはセーブデータのパネルを設定します。confirmationPanelはセーブファイルを選択した後に本当にセーブするかどうかの選択パネルを設定します。dataResultPanelは『セーブしました。』みたいなのを表示するパネルを設定します。dataPanelCanvasGroupはdataPanelに設定したCanvasGroupを設定します。confirmationPanelCanvasGroupはconfirmationPanelに設定したCanvasGroupを設定します。saveDataScriptは先ほど作ったSaveDataScriptを設定します。savingはセーブ中かどうかです。Awakeメソッドに追加Awakeメソッドにゲームオブジェクトを取得する処理、CanvasGroupを取得する処理を追記します。FindObjectOfType<SaveDataScript>();SaveDataScriptは一つしか存在しないのでFindObjectOfTypeで取得しています。OnEnableメソッドに追加OnEnableメソッドにはパネルの非表示とCanvasGroupのinteractableの無効化を行う処理を追加します。false;Updateメソッドに追加Updateメソッドにセーブ中は何もしない処理と、Cancelボタンを押した時の処理を追加します。Updateメソッドの最初でセーブ中はreturnでそれ以降の処理をしないようにします。{return;}Cancelボタンの処理にcurrentCommnadがCommandMode.DataPanel、CommandMode.ConfirmationPanelの時の処理を追加します。CommandMode.DataPanel;}Cancelボタンを押した時に前のパネルに戻る処理を記述しているだけで以前作成した処理と同じ事をしているだけです。EventSystemの選択が解除された時の処理にCommandMode.DataPanelとCommandMode.ConfirmationPanelの時の処理を追加します。次はどのコマンドを選択したかを処理しているSelectCommandメソッドの処理を変更します。true;EventSystem.current.SetSelectedGameObject(selectCharacterPanel.transform.GetChild(0).gameObject);}}最初のStatusとItemの時は以前と同じなので省略しています。Saveの時はcommandPanelCanvasGroupのinteractableをfalseにしCommandPanelのUIを選択出来ないようにします。この時選択していたセーブコマンドのボタンをselectedGameObjectStackにプッシュして保持しておきます。その後Saveの時はSaveDataScriptのDisplayDataメソッドを実行し、ボタンのテキストにセーブデータの情報を表示します。dataPanelをアクティブにし操作出来るようにします。Save以外の時は以前からあった処理と同じです。確認パネル表示メソッドの追加セーブコマンドで3つのセーブデータのうちどれかを押した時に実行した時に表示するパネルの表示処理であるDisplayConfirmPanelを作成します。true;EventSystem.current.SetSelectedGameObject(confirmationPanel.transform.Find("Panel/OKButton").gameObject);}引数でセーブデータの番号を受け取ります。確認パネル(confirmationPanel)の子要素のOKButtonとCancelButtonのButtonコンポーネントを取得し、最初にボタンを押した時に実行するメソッドの登録を全削除します。これはボタンにはスクリプトから実行するメソッドを取り付けますが、DisplayConfirmPanelメソッドを実行する度に追加していると2重3重に取り付けたメソッドが実行されてしまう為です。その後取得したButtonコンポーネントのonClickにAddListenerでOKButtonを押したらSaveメソッド、CancelButtonを押したらReturnToDataPanelメソッドを実行するようにリスナーを登録します。ここら辺の処理はアイテムコマンドの辺りで嫌というほどやりましたので問題はないかと思います。(^_^;)EventSystem.current.SetSelectedGameObjectを使って、確認パネルを表示したらOKButtonが選択状態になるようにします。実際のデータのセーブはSaveDataScriptで行いますが、CommandScriptでもSaveDataScriptのSaveメソッドと同一の名前のメソッドを追加します。CommandScriptのSaveメソッドはSaveDataScriptのSaveメソッドを呼び出して、実際の処理をさせます。false;confirmationPanel.SetActive(false);dataPanel.SetActive(false);saveDataScript.Save(dataNum);StartCoroutine(ProcessingAfterSaving(dataNum));}行っていることは今までと同じでパネルの非表示やCanvasGroupの無効化等をしている部分はアイテムコマンドの時と同じなので問題はないと思います。SaveDataScriptのSaveメソッドを引数にセーブデータ番号を渡して呼び出します。その後『セーブしました』みたいなメッセージを一定時間表示する為、コルーチンを使ってProcessingAfterSavingメソッドを呼び出します。セーブしましたメッセージ表示処理セーブ後に『セーブしました』というメッセージを一定時間表示するメソッドを追加します。"にデータを保存しました。"にデータを保存しました。true;selectedGameObjectStack.Pop();EventSystem.current.SetSelectedGameObject(selectedGameObjectStack.Pop());}最初にdataResultPanelのテキストにデータを保存しましたのようなテキストを設定し、dataResultPanelを表示します。WaitForSeconds(1f)で1秒間待機した後、コマンド選択パネルに戻すようにします。confirmationPanelを開いている状態ではCommandPanelのボタンとDataPanelのボタンのゲームオブジェクトがselectedGameObjectStackに登録されていて、confirmationPanelから一気にCommandPanelに戻るので一つそのまま空で捨てた後に、CommandPanelのボタンを選択している状態にします。確認パネル(ConfirmationPanel)でキャンセルボタンを押してセーブするのをやめた時の処理を記述します。true;EventSystem.current.SetSelectedGameObject(selectedGameObjectStack.Pop());}やる事は単純にDataPanelでどのデータファイルにセーブするかの選択状態に戻すだけです。これでCommandScriptへの処理の追加が終わりました。(-_-)CommandUIにセーブコマンドUIを追加するステータスコマンド、アイテムコマンドのパネルに新しくセーブコマンドのUIを追加していきます。VillageシーンのCommandの子要素のCommandPanelの子要素のItemButtonを選択した状態でCtrl+Dキーをおして複製し、名前をSaveButtonとします。SaveButtonのButtonのOnClickにCommandゲームオブジェクトをドラッグ&ドロップし、実行するメソッドにSelectCommandを設定しその下にSaveという文字列を入力します。Commandゲームオブジェクトを選択した状態で右クリックからUI→Panelを選択し、名前をDataPanelとします。Groupを取り付けます。ExpandのWidthとHeightにチェックを入れます。Groupの設定によってサイズが調整されます。CanvasGroupのinteractableのチェックを外しDataPanelの子要素のUIは最初は選択出来ないようにします。DataPanelを選択した状態で右クリックからUI→Buttonを選択し、名前をData1Buttonとします。ImageのColorは白色、Buttonの状態に応じた色は適当に設定してください。Color)の色を同じにしました。Data1Buttonが押された時はCommandScriptのDisplayConfirmPanelメソッドに1を渡して実行します。Data1Buttonの子要素のTextの設定をします。Sizeを25、ParagraphのAlignmentを左寄せの中段表示にします。Data1Buttonを選択した状態でCtrl+Dキーを押して複製し、Data2ButtonとData3Buttonを作成します。Data2ButtonとData3ButtonのOnClickのDisplayConfirmPanelメソッドへ渡す数値はそれぞれ2と3に変更しておきます。DataPanelは以下のようになりました。ゲーム画面全体より少し小さいぐらいにしました。次にCommandを選択した状態で右クリックからPanelを選択し、名前をConfirmationPanelとします。ConfirmationPanelにもCanvasGroupを取り付け、interactableのチェックを外しておきます。ConfirmationPanelを選択した状態で右クリックからUI→Textを選択し、名前をTitleTextとします。TitleTextはConfirmationPanelの上部に位置するように移動します。Textには『データを上書きしてもよろしいですか?』という文字列を入力します。ConfirmationPanelを選択した状態で右クリックからUI→Panelを選択します。Groupを取り付けます。Centerにし子要素が中央に表示されるようにします。Panelを選択した状態で右クリックからUI→Buttonを選択し、名前をOKButtonとします。OKButtonのボタンの状態に応じた色を変更します。OKButtonを押した時の処理はスクリプトから設定したのでOnClickには何も設定しません。OKButtonを選択した状態でCtrl+Dキーを押して複製し、名前をCancelButtonとします。OKButtonの子要素のTextのTextには『OK』、CancelButtonの子要素のTextのTextには『キャンセル』と入力します。Sizeは25としました。出来たConfirmationPanelは以下のようになりました。ConfirmationPanelを選択した状態でCtrl+Dキーを押して複製し、名前をDataResultPanelとします。DataResultPanelの子要素を全部削除し、新しくUI→Textを作成します。Textは以下のように設定します。Textに『データが上書きされました』と入力しますが、スクリプトから上書きしているので特に入力しなくてもいいです。これでUIが出来、以下のような階層になりました。DataPanel、ConfirmationPanel、DataResultPanelのインスペクタの名前の横のチェックを外し、最初は表示されないようにしておきます。これでUIが出来たので、SaveManagerゲームオブジェクトのSaveDataScriptの設定をします。上のようにステータスデータの設定と、データ名、UIの設定をします。Villageシーンではユニティちゃんの位置と角度は保存しないのでUnityChanTransformには何も設定しません。WorldMapシーンにUIやSaveManagerゲームオブジェクト等を複製するVillageシーンでのセーブ機能が出来たのでこれをWorldMapシーンにCommandをコピーして貼り付け、SaveManagerゲームオブジェクトをコピーして貼り付けます。UIの設定等はそれぞれのシーンのUIやスクリプト等に変更してください。変更する箇所としてはDataPanel子要素の3つのボタンをWorldMapシーンのCommandScriptのDisplayConfirmPanelメソッドに変更。SaveManagerゲームオブジェクトのSaveDataScriptのUIの設定と、unityChanTransformにWorldMapシーンのヒエラルキーのUnityChanを設定。これでデータのセーブ機能が出来ました。ロード機能の作成セーブ機能が出来たので次はロード機能を作成します。今回はロードはTitleシーンでのみ行えるようにします。UIの作成まずはVillageシーンを開き、DataPanelゲームオブジェクトとConfirmationPanelゲームオブジェクトをコピーし、TitleシーンのCanvasの子要素の貼り付けます。TransformのLeftやRight等を0にします。ScaleのXYZが0になっている可能性があるので、1にします。Canvasを選択した状態で右クリックからUI→Panelを選択し、名前をMainPanelとします。Groupを取り付けます。GroupのTopとBottomを調整して子要素に配置するボタンの並びを変更します。Groupのinteractableにはチェックを入れておきます。作成してあるStartButtonをMainPanelの子要素にドラッグし、StartButtonを選択した状態でCtrl+Dキーを押して複製し、名前をContinueButtonとします。ContinueButton子要素のTextには『つづきから』と入力します。MainPanelのサイズやボタンの配置等は以下のようにしました。ロード、削除機能のスクリプトを作成ロード機能のスクリプトを作成していきます。Emptyを選択し、名前をCommandManagerとします。Assets/RPG/Scrptsフォルダに新しくLoadDataScriptを作成し、CommandManagerゲームオブジェクトに取り付けます。スクリプトが長いので分割して説明します。クラス定義とフィールドまずはクラス定義とフィールドです。saveData3;}データのロードをしてゲームを再開する時にシーンを読み込む必要があるためLoadSceneManagerスクリプトを設定出来るようにしておきます。後のフィールドはキャラクターのステータスやセーブデータ名とセーブデータのTextを設定します。StartメソッドStartメソッドを作成します。FindObjectOfType<LoadSceneManager>();}StartメソッドでLoadSceneManagerスクリプトを取得しています。データ情報を表示する処理データ情報を表示する処理DisplayDataメソッドを記述します。"データがありません。"データがありません。"データがありません。"データがありません。"データがありません。"データがありません。";}}}}SaveDataScriptのDisplayDataメソッドとほとんど同じです。データの読み込み処理データの読み込み処理を行うLoadメソッドを記述します。Debug.Log("データがありません。{Debug.Log("データがありません。");}}引数でセーブデータの番号を受け取り、そのデータが存在していればそのJSONデータをDataクラスのdataに入れます。あとはユニティちゃんのステータス(unityChanStatus)や大鳥ゆうじのステータス(yujiStatus)のフィールドの設定メソッドにdataのデータを設定するだけです。最後にLoadSceneManagerスクリプトのGoToNextSceneメソッドをdata.ScenTypeを引数に渡して呼び出し、シーン遷移をします。LoadSceneManagerスクリプトに処理を追加セーブ機能でSceneMovementDataスクリプトのSceneTypeにWorldMapを追加したので、ロード時のシーンタイプを比較しているFadeAndLoadSceneメソッド内にWorldMapも追加します。StartCoroutine(LoadScene("WorldMap"));}PartyStatusスクリプトにCreateAllyStatusメソッドを作成するAssets/RPG/Scripts/Status/PartyStatusスクリプトに追記します。次は削除機能を作成します。MainPanelのContinueButtonを選択した状態でCtrl+Dキーを押して複製し、名前をDeleteButtonとします。Assets/RPG/Scriptsフォルダに新しくDeleteDataScriptスクリプトを作成し、CommandManagerゲームオブジェクトに取り付けます。{PlayerPrefs.DeleteKey(dataName);}}}Deleteメソッドは引数で受け取ったデータがあるかどうか調べ、あれば削除しています。タイトルシーン用のコマンド操作スクリプトの作成ロード機能と削除機能が出来たので次はタイトルシーンでもVillageシーンでコマンド処理用のCommandScriptスクリプトのようにパネルとCanvasGroupの操作をするスクリプトを作成します。Assets/RPG/Scriptsフォルダに新しくTitleCommandScirptスクリプトを作成します。TitleCommandScriptはCommandManagerゲームオブジェクトに取り付けます。スクリプトは分割して説明します。基本的には以前作成したCommandScriptの簡易版だと思って頂ければいいと思います。クラス定義とフィールドまずはクラス定義とフィールドです。deleting;}列挙型のCommandModeは現在どのパネルを開いている状態かを表しています。currentModeは現在のCommandModeを入れます。loadDataScriptは先ほど作成したLoadDataScriptを入れます。mainPanelは『はじめから』と『つづきから』『データを削除』のボタンの親のMainPanelを設定します。dataPanelはセーブデータを表示しているパネルを設定します。Groupを設定します。confirmationPanelはセーブデータをロードするかの最終確認パネルを設定します。Groupを設定します。dataResultPanelはデータを削除時に使用するパネルです。data1Buttonからdata3ButtonまではDataPanelの子要素のボタンを設定します。okButtonとcancelButtonはConfirmationPanelの子要素のOKButtonとCancelButtonを設定します。selectedGameObjectStackは新しいパネルを開いた時に前のパネルのゲームオブジェクトを登録しておいて、前のパネルに戻った時にそのゲームオブジェクトを選択しなおす時に使用します。dataNameはセーブデータの名前を設定します。deletingは現在削除中かどうかです。StartとUpdateメソッドStartとUpdateメソッドを作成していきます。{EventSystem.current.SetSelectedGameObject(confirmationPanel.transform.Find("Panel/OKButton").gameObject);}}}StartメソッドでFindObjectOfTypeでヒエラルキー上にひとつだけあるLoadDataScritpとDeleteDataScriptを探して取得します。その他のボタンも各パネルの階層から取得しておきます。Updateメソッドではデータを削除中はその後の処理はしないようにします。Cancelボタンを押した時の処理で、現在のcurrentCommandに応じてパネルを戻る処理を実行します。確認パネル(CommandMode.ConfirmationPanel)の場合はSelectCommandにBackという文字列を渡してDataPanelの表示に戻します。マウス等でボタン外を押した時にボタンからフォーカスが外れるのを防ぐため、EventSystemがどのUIも選択状態でなければ現在のコマンドモードに応じて該当するボタンを強制的に選択状態にします。実行コマンドの処理分け選択したコマンドに応じた処理分けをするSelectCommandメソッドを作成します。{EventSystem.current.SetSelectedGameObject(selectedGameObjectStack.Pop());}}引数で受け取った文字列のコマンドに応じて実行する処理分けをしています。ここではdataPanel(セーブデータファイル表示)の表示とconfirmationPanel(確認パネル)の非表示を行います。commandがLoadの場合はconfirmationPanelの表示と、そのCanvasGroupを無効化する処理はいらないですが、confirmationPanelを開いている状態でキャンセルした時(commandがBackの時)に必要になるので実行しています。if文で条件に応じて実行させるようにしてもいいです。commandがLoadかDeleteの時は現在選択しているゲームオブジェクト(MainPanelのContinueButtonゲームオブジェクト)をselectedGameObjectStackにプッシュしておき、LoadDataScriptのDisplayDataメソッドを呼び出してmainPanelのボタンにデータ情報を表示します。data1Button等のボタンが押された時に実行する処理をRemoveAllListenerを使って全削除します。セーブデータがあるかどうかを調べ、セーブデータがあるボタンが押された時だけ実行するメソッドを登録する事にします。その後dataPanelの最初の子要素を選択状態にします。commandがBackの時はconfirmationPanelでCancelButtonを押して戻ってきた時の処理なので、selectedGameObjectStackからポップしたゲームオブジェクト(confirmationPanelを開く前に選択していたボタン)を選択状態にします。確認パネルを表示するDisplayLoadConfirmPanelメソッドを作成します。true;EventSystem.current.SetSelectedGameObject(confirmationPanel.transform.Find("Panel/OKButton").gameObject);}DisplayConfirmPanelメソッドは何をするかというcommandと何番目のデータか?という情報を引数で受け取ります。最初にokButtonとcancelButtonに取り付けてあるリスナーを削除します。次にcommandがLoadの時とDeleteの時で処理を分けます。confirmationPanelのTitleTextのTextをcommandに応じて変更します。okButtonが押された時にcommandがLoadであればLoadDataScriptのLoadメソッドを実行するようにします。DeleteであればDeleteメソッドを実行するようにします。cancelButtonが押された時はcommandがLoadであれDeleteであれSelectCommandメソッドを実行します。データ削除要請処理データ削除をDeleteDataScriptに要請する処理を作成します。dataNum);StartCoroutine(ProcessingAfterDeleting(dataNum));}データの削除処理をした後コルーチンを使ってProcessingAfterDeletingメソッドを呼び出します。データ削除後の処理データ削除後の処理ProcessingAfterDeletingメソッドを作成します。