UnityでCSVファイルを読んでみる!
こんにちは「つけらっとゲームス」プログラム担当のとちです。
以前「縦スクロールSTGを作ってみた!」という記事の中で敵機をCSVファイルで管理しているという話をしました。
ゲーム規模が大きくなるとデータ編集が大変になりますよね。
敵機が山ほど出てくるゲームだと、コード内に各種データを書くのも大変。エディタで初期配置しまくるのも大変です。
「だったらExcelでデータを作り、CSV形式で吐き出してUnityで読もう!」
というのが今回のテーマです。
※「とりあえずUnityでCSVファイルを読めたらそれでいい!」という方は、目次から「スクリプト詳細」の「データファイルの取り扱い(1~2)」だけをご覧ください。
データをCSV化する意図
個人レベル、または小規模チームで開発するインディーゲームですとExcelで十二分に管理できますが、大量のデータ管理をするならデータベースソフトを使う方がいいかもです。
どちらにせよ、データをエクスポートしてCSV化しちゃえば、外からUnityにデータを入れることができます。
プログラムコード内にデータを書く、またはエディタで初期配置してもいいのですがUnityを触れない方がチーム内にいて、その人にデータ入力を手伝ってもらうなら普段使いのExcel(などの表計算ソフト)がいいでしょう。
んで、CSV、CSVって言ってますけど、まずCSVとは何なのか?
CSV(Comma Separated Values)ファイルは、カンマ「,」で項目を区切っているテキストデータです。中身がテキストデータなのでサイズも小さいし、前述したとおり色々なソフトで編集できるのが良いですね。
例で使用するデータ
例を挙げて説明した方がわかりやすいと思います。そこで今回のデータ例を作ったので、さっそく登場してもらいましょう。こんなデータです!
見覚えのあるデータが並んでいます。DQ2の武器と防具のデータですね。
何度かリメイクされているので「こんなんあったっけ?」というデータが含まれているかもしれません。
余談ですが、DQ3リメイクが間もなく発売なので、例のデータはDQ3にしようかなと思ったんです。しかし、DQ3は職業別の装備可否でデータ量が増えるので今回はDQ2で許してください…
というわけで、見た目通りExcelで作りました。
これをCSVにしましょう。「名前を付けて保存」を選んで…
「ファイルの種類」を「CSV UTF-8(コンマ区切り)(*.csv)」にして保存してください。
すこし下の方をみると「CSV (コンマ区切り)(*.csv)」という選択肢もあるんですが、文字コードが「シフトJIS」だとUnityで文字化けしちゃうので手間が増えます。
もしお使いの表計算ソフトでCSV化する時に文字コード変換できない場合でも大丈夫。Windows付属のメモ帳でも文字コードを変更できます。
作ったCSVファイルをメモ帳で開いて「名前を付けて保存」を選びます。
スクショのようにエンコードをUTF-8(BOM付き)にしましょう。
となると「BOMってなんやねん?」となりますよね。
バイトオーダーマーク(Byte Order Mark)ってやつでして、これがあると「UTF-8ですよー」っていうマークを付けてるんです。これによって、このファイルをExcelを開くときUTF-8の文字コードで表示するんですね。
例で使用するCSVファイルも添付しておきますね。
例でこんなの作りました
Unityでこんな画面を用意しました。
画面の左上に「武器」「防具」と書かれている入力欄がありますね。ここに武器や防具の名前を入力すると…
CSVファイルで読み込んだデータを編集して表示します。
武器欄に「ひかりのつるぎ」と入力したら以下の画面が表示されますし、
防具欄に「まほうのよろい」と入力したら以下の画面が表示されます。
スクリプトの中にも、これらのデータは入っていませんし、エディタの初期配置であらかじめ準備したものでもありません。
スクリプト全体
とりあえずスクリプト全体を貼り付けますね。
コード内のコメントにもある通り、武器名称から該当する武器データを呼び出します。
using UnityEngine;
using System.IO;
using System;
using TMPro;
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//
// 【武器名称からデータを探索し表示する】
// Assetsフォルダの外にあるファイルをFileStream,StreamReaderで読む
//
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
public class CMain_Buki : MonoBehaviour //
{ //
string[] bName = new string[20]; //【変数定義】武器名称
int[] bKouka = new int[20]; //【 〃 】武器効果(攻撃力)
int[] bKaine = new int[20]; //【 〃 】買値
int[] bUrine = new int[20]; //【 〃 】売値
int[] bSoubi1 = new int[20]; //【 〃 】ローレシアの王子 装備スイッチ [0]不可 [1]可
int[] bSoubi2 = new int[20]; //【 〃 】サマルトリアの王子 装備スイッチ [0]不可 [1]可
int[] bSoubi3 = new int[20]; //【 〃 】ムーンブルクの王女 装備スイッチ [0]不可 [1]可
string[] bBikou = new string[20]; //【 〃 】備考
GameObject[] TMPObj = new GameObject[8]; //【 〃 】ゲームオブジェクト配列
//
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// Start
//
// 引数 なし
//
// 戻値 なし
//
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
void Start() //
{ //
QualitySettings.vSyncCount = 0; // VSyncをOFFにする
Application.targetFrameRate = 60; // fpsを60にする
//
string DataPath = "csvData/DQ2Buki.csv"; //【変数定義】武器データ(CSVファイルパス )
FileStream DataFile = new FileStream(DataPath,FileMode.Open,FileAccess.Read); //【 〃 】 〃 (ファイルストリーム)
StreamReader DataReader = new StreamReader(DataFile); //【 〃 】 〃 (ストリームリーダー)
int ix = 0; //【 〃 】配列用添字
//
while(DataReader.Peek() != -1) // ■ファイルの最後まで繰返
{ // │
string LineData = DataReader.ReadLine(); // ├【変数定義】武器データ1行だけ(1行だけ読込)
string[] LineSplit = LineData.Split(','); // ├【 〃 】武器データを,記号で分割して配列化
// │
bName[ix] = LineSplit[0]; // ├ 配列に代入 武器名称
bKouka[ix] = int.Parse(LineSplit[1]); // ├ 〃 武器効果(数字化)
bKaine[ix] = int.Parse(LineSplit[2]); // ├ 〃 買値 ( 〃 )
bUrine[ix] = int.Parse(LineSplit[3]); // ├ 〃 売値 ( 〃 )
bSoubi1[ix] = int.Parse(LineSplit[4]); // ├ 〃 ローレ装( 〃 )
bSoubi2[ix] = int.Parse(LineSplit[5]); // ├ 〃 サマル装( 〃 )
bSoubi3[ix] = int.Parse(LineSplit[6]); // ├ 〃 ムーン装( 〃 )
bBikou[ix] = LineSplit[7]; // ├ 〃 備考
ix++; // └ 配列用添字 +1
} //
DataReader.Close(); // ファイルクローズ
//
TMPObj[0] = GameObject.Find("Input_Buki"); // 配列に代入 名称入力枠
TMPObj[1] = GameObject.Find("Name"); // 〃 名称
TMPObj[2] = GameObject.Find("Kouka"); // 〃 効果
TMPObj[3] = GameObject.Find("Kaine"); // 〃 買値
TMPObj[4] = GameObject.Find("Urine"); // 〃 売値
TMPObj[5] = GameObject.Find("Soubi"); // 〃 装備可否表示欄
TMPObj[6] = GameObject.Find("Bikou"); // 〃 備考
TMPObj[7] = GameObject.Find("KoukaT"); // 〃 効果(項目名)
} //
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// EditEndDisp
//
// 引数 なし
//
// 戻値 なし
//
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
public void EditEndDisp() //
{ //
string InpTxt = TMPObj[0].GetComponent<TMP_InputField>().text; //【変数定義】武器名称 (名称入力欄から取得)
int bIx = Array.IndexOf(bName,InpTxt); //【変数定義】配列用添字(入力された名称と同じ武器名のindex取得)
//
if(bIx >= 0) // ■添字が0以上(見つからない場合は-1なので処理しない)
{ // │
string wSoubi = ""; // ├【変数定義】装備可否表示の文字列編集エリア
if(bSoubi1[bIx] >= 1){wSoubi += "ローレシア ";} // ├◆ローレシアの王子 装備可の場合は文字列編集エリアに代入
if(bSoubi2[bIx] >= 1){wSoubi += "サマルトリア ";} // ├◆サマルトリアの王子 装備可の場合は文字列編集エリアに代入
if(bSoubi3[bIx] >= 1){wSoubi += "ムーンブルク";} // ├◆ムーンブルクの王女 装備可の場合は文字列編集エリアに代入
// │
TMPObj[1].GetComponent<TextMeshProUGUI>().text = bName[bIx]; // ├ 画面表示 武器名称
TMPObj[2].GetComponent<TextMeshProUGUI>().text = bKouka[bIx] + ""; // ├ 〃 武器効果(文字列化)
TMPObj[3].GetComponent<TextMeshProUGUI>().text = bKaine[bIx] + ""; // ├ 〃 買値 (文字列化)
TMPObj[4].GetComponent<TextMeshProUGUI>().text = bUrine[bIx] + ""; // ├ 〃 売値 (文字列化)
TMPObj[5].GetComponent<TextMeshProUGUI>().text = wSoubi; // ├ 〃 装備可否
TMPObj[6].GetComponent<TextMeshProUGUI>().text = bBikou[bIx]; // ├ 〃 備考
TMPObj[7].GetComponent<TextMeshProUGUI>().text = "攻撃力"; // └ 〃 効果の項目名を攻撃力に変更
} //
} //
} //
次はコチラ、コード内のコメントにもある通り、防具名称から該当する防具データを呼び出します。
using UnityEngine;
using System.IO;
using System;
using TMPro;
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//
// 【防具名称からデータを探索し表示する】
// Assetsフォルダ内(Resourcesフォルダ内)にあるファイルをTextAsset,StringReaderで読む
//
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
public class CMain_Bougu : MonoBehaviour //
{ //
string[] bName = new string[20]; //【変数定義】防具名称
int[] bKouka = new int[20]; //【 〃 】防具効果(防御力)
int[] bKaine = new int[20]; //【 〃 】買値
int[] bUrine = new int[20]; //【 〃 】売値
int[] bSoubi1 = new int[20]; //【 〃 】ローレシアの王子 装備スイッチ [0]不可 [1]可
int[] bSoubi2 = new int[20]; //【 〃 】サマルトリアの王子 装備スイッチ [0]不可 [1]可
int[] bSoubi3 = new int[20]; //【 〃 】ムーンブルクの王女 装備スイッチ [0]不可 [1]可
string[] bBikou = new string[20]; //【 〃 】備考
GameObject[] TMPObj = new GameObject[8]; //【 〃 】ゲームオブジェクト配列
//
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// Start
//
// 引数 なし
//
// 戻値 なし
//
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
void Start() //
{ //
string DataPath = "DataArea/DQ2Bougu"; //【変数定義】防具データ(CSVファイルパス )
TextAsset DataAsset = (TextAsset)Resources.Load(DataPath); //【 〃 】 〃 (テキストアセット )
StringReader DataReader = new StringReader(DataAsset.text); //【 〃 】 〃 (ストリングリーダー)
int ix = 0; //【 〃 】配列用添字
//
while(DataReader.Peek() != -1) // ■ファイルの最後まで繰返
{ // │
string LineData = DataReader.ReadLine(); // ├【変数定義】防具データ1行だけ(1行だけ読込)
string[] LineSplit = LineData.Split(','); // ├【 〃 】防具データを,記号で分割して配列化
// │
bName[ix] = LineSplit[0]; // ├ 配列に代入 防具名称
bKouka[ix] = int.Parse(LineSplit[1]); // ├ 〃 防具効果(数字化)
bKaine[ix] = int.Parse(LineSplit[2]); // ├ 〃 買値 ( 〃 )
bUrine[ix] = int.Parse(LineSplit[3]); // ├ 〃 売値 ( 〃 )
bSoubi1[ix] = int.Parse(LineSplit[4]); // ├ 〃 ローレ装( 〃 )
bSoubi2[ix] = int.Parse(LineSplit[5]); // ├ 〃 サマル装( 〃 )
bSoubi3[ix] = int.Parse(LineSplit[6]); // ├ 〃 ムーン装( 〃 )
bBikou[ix] = LineSplit[7]; // ├ 〃 備考
ix++; // └ 配列用添字 +1
} //
//
TMPObj[0] = GameObject.Find("Input_Bougu"); // 配列に代入 名称入力枠
TMPObj[1] = GameObject.Find("Name"); // 〃 名称
TMPObj[2] = GameObject.Find("Kouka"); // 〃 効果
TMPObj[3] = GameObject.Find("Kaine"); // 〃 買値
TMPObj[4] = GameObject.Find("Urine"); // 〃 売値
TMPObj[5] = GameObject.Find("Soubi"); // 〃 装備可否表示欄
TMPObj[6] = GameObject.Find("Bikou"); // 〃 備考
TMPObj[7] = GameObject.Find("KoukaT"); // 〃 効果(項目名)
} //
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// EditEndDisp
//
// 引数 なし
//
// 戻値 なし
//
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
public void EditEndDisp() //
{ //
string InpTxt = TMPObj[0].GetComponent<TMP_InputField>().text; //【変数定義】防具名称 (名称入力欄から取得)
int bIx = Array.IndexOf(bName,InpTxt); //【変数定義】配列用添字(入力された名称と同じ防具名のindex取得)
//
if(bIx >= 0) // ■添字が0以上(見つからない場合は-1なので処理しない)
{ // │
string wSoubi = ""; // ├【変数定義】装備可否表示の文字列編集エリア
if(bSoubi1[bIx] >= 1){wSoubi += "ローレシア ";} // ├◆ローレシアの王子 装備可の場合は文字列編集エリアに代入
if(bSoubi2[bIx] >= 1){wSoubi += "サマルトリア ";} // ├◆サマルトリアの王子 装備可の場合は文字列編集エリアに代入
if(bSoubi3[bIx] >= 1){wSoubi += "ムーンブルク";} // ├◆ムーンブルクの王女 装備可の場合は文字列編集エリアに代入
// │
TMPObj[1].GetComponent<TextMeshProUGUI>().text = bName[bIx]; // ├ 画面表示 防具名称
TMPObj[2].GetComponent<TextMeshProUGUI>().text = bKouka[bIx] + ""; // ├ 〃 防具効果(文字列化)
TMPObj[3].GetComponent<TextMeshProUGUI>().text = bKaine[bIx] + ""; // ├ 〃 買値 (文字列化)
TMPObj[4].GetComponent<TextMeshProUGUI>().text = bUrine[bIx] + ""; // ├ 〃 売値 (文字列化)
TMPObj[5].GetComponent<TextMeshProUGUI>().text = wSoubi; // ├ 〃 装備可否
TMPObj[6].GetComponent<TextMeshProUGUI>().text = bBikou[bIx]; // ├ 〃 備考
TMPObj[7].GetComponent<TextMeshProUGUI>().text = "防御力"; // └ 〃 効果の項目名を防御力に変更
} //
} //
} //
よく見るとわかりますが、この2つのスクリプトほぼ同じです。
違う箇所はどこでしょう?
「武器」「攻撃力」「防具」「防御力」という表記の違いやフレームレートの設定以外で異なる点は次の部分です。
武器のスクリプトでは、こんな記述になっているところが…
string DataPath = "csvData/DQ2Buki.csv"; //【変数定義】武器データ(CSVファイルパス )
FileStream DataFile = new FileStream(DataPath,FileMode.Open,FileAccess.Read); //【 〃 】 〃 (ファイルストリーム)
StreamReader DataReader = new StreamReader(DataFile); //【 〃 】 〃 (ストリームリーダー)
防具のスクリプトでは、こんな記述なっているんです。
string DataPath = "DataArea/DQ2Bougu"; //【変数定義】防具データ(CSVファイルパス )
TextAsset DataAsset = (TextAsset)Resources.Load(DataPath); //【 〃 】 〃 (テキストアセット )
StringReader DataReader = new StringReader(DataAsset.text); //【 〃 】 〃 (ストリングリーダー)
そして読んでいるCSVファイルのパスが違います。
武器データはAssetsフォルダ外にあるファイルを読んでいますが、防具データは、Assets/Resourcesフォルダにあります。
また、Assets/ResourcesフォルダにあるファイルをTextAssetを使用して読む場合はメモリ上のデータなのでファイルクローズをしなくてもいいです。
…ということは、ゲーム内で編集したファイルを別件でも使用する場合はAssetsフォルダの外に置かないといけません(ビルド前だったらどこに置いても問題ないんでしょうけど…)
スクリプト詳細
それではスクリプトの中身を細かく見ていきましょう。
コード内のコメントにも、その行が何をやっているか書いているので参考にしてくださいね。
変数定義部
string[] bName = new string[20]; //【変数定義】武器名称
int[] bKouka = new int[20]; //【 〃 】武器効果(攻撃力)
int[] bKaine = new int[20]; //【 〃 】買値
int[] bUrine = new int[20]; //【 〃 】売値
int[] bSoubi1 = new int[20]; //【 〃 】ローレシアの王子 装備スイッチ [0]不可 [1]可
int[] bSoubi2 = new int[20]; //【 〃 】サマルトリアの王子 装備スイッチ [0]不可 [1]可
int[] bSoubi3 = new int[20]; //【 〃 】ムーンブルクの王女 装備スイッチ [0]不可 [1]可
string[] bBikou = new string[20]; //【 〃 】備考
GameObject[] TMPObj = new GameObject[8]; //【 〃 】ゲームオブジェクト配列
武器または防具の種類が20種類以下なので、とりあえず20個の変数配列を設けました。二次元配列でもいいのですがコチラの方が見やすいかな?
CSVファイルの項目と同じように変数定義をしています。
TMPObjはテキストメッシュProのオブジェクトを配列で持っています。
各項目を画面表示するオブジェクトを格納する変数配列です。
データファイルの取り扱い(1)
次に武器ファイルを読む前にファイルオープンをしている部分です。
string DataPath = "csvData/DQ2Buki.csv"; //【変数定義】武器データ(CSVファイルパス )
FileStream DataFile = new FileStream(DataPath,FileMode.Open,FileAccess.Read); //【 〃 】 〃 (ファイルストリーム)
StreamReader DataReader = new StreamReader(DataFile); //【 〃 】 〃 (ストリームリーダー)
int ix = 0; //【 〃 】配列用添字
String DataPath は変数名の通りCSVファイルのパスを書いています。
Assetsフォルダの外にあるcsvDataフォルダにあるDQ2Buki.csvのパスです。
FileStream DataFile の行では読む目的でファイルをオープンしてます。
StreamReader DataReader の行で開いたファイルを指定しています。
int ix は配列用の添字。配列は0からなので初期値として0を入れてます。
データファイルの取り扱い(2)
コチラは防具ファイルを読む部分です。
string DataPath = "DataArea/DQ2Bougu"; //【変数定義】防具データ(CSVファイルパス )
TextAsset DataAsset = (TextAsset)Resources.Load(DataPath); //【 〃 】 〃 (テキストアセット )
StringReader DataReader = new StringReader(DataAsset.text); //【 〃 】 〃 (ストリングリーダー)
int ix = 0; //【 〃 】配列用添字
String DataPath は武器ファイルのスクリプトと同様にファイルパスです。
Aseets/Resources/DataAreaフォルダにあるDQ2Bougu.csvのパスです。
TextAsset DataAsset の行では先程のパスのファイルをTextAsset型で読み込んでいます。StringReader DataReader の行ではDataAssetのTextをDataReaderに定義しています。
StreamReader と StringReader 見た感じ似ているので注意が必要です!
int ix は配列用の添字。これは武器ファイル側と同じですね。
行単位で読んで配列に代入
ここでは実際に読み込んだデータを各配列に代入しています。
while(DataReader.Peek() != -1) // ■ファイルの最後まで繰返
{ // │
string LineData = DataReader.ReadLine(); // ├【変数定義】武器データ1行だけ(1行だけ読込)
string[] LineSplit = LineData.Split(','); // ├【 〃 】武器データを,記号で分割して配列化
// │
bName[ix] = LineSplit[0]; // ├ 配列に代入 武器名称
bKouka[ix] = int.Parse(LineSplit[1]); // ├ 〃 武器効果(数字化)
bKaine[ix] = int.Parse(LineSplit[2]); // ├ 〃 買値 ( 〃 )
bUrine[ix] = int.Parse(LineSplit[3]); // ├ 〃 売値 ( 〃 )
bSoubi1[ix] = int.Parse(LineSplit[4]); // ├ 〃 ローレ装( 〃 )
bSoubi2[ix] = int.Parse(LineSplit[5]); // ├ 〃 サマル装( 〃 )
bSoubi3[ix] = int.Parse(LineSplit[6]); // ├ 〃 ムーン装( 〃 )
bBikou[ix] = LineSplit[7]; // ├ 〃 備考
ix++; // └ 配列用添字 +1
} //
DataReader.Close(); // ファイルクローズ
while(DataReader.Peek() != -1) は繰り返し処理の開始を意味します。
終了条件は括弧の中に書かれています。Peekメソッドは読み取る文字が無い場合に「-1」を返します。つまり「-1」ではない場合は繰り返します。
string LineData = DataReader.ReadLine(); はデータを1行読んでLineDataに代入します。
string[] LineSplit = LineData.Split(','); で読んだデータをカンマ「,」で区切ってLineSplit配列に格納します。これでCSVファイルの項目が分割されるので便利ですね!
bName[ix] = LineSplit[0]; で分割された最初の項目を武器または防具名称としてbName[ix]に格納しています。
bKouka[ix] = int.Parse(LineSplit[1]); ここから似ている行が続きます。
分割された項目は文字列で取得しているので数字データを文字から数字化しています。
bBikou[ix] = LineSplit[7]; 備考は文字列でいいのでint.Parseは不要です。
ix++ は配列の添字を1つ増やしています。
DataReader.Close(); はファイルを閉じています。但しAssets/ResourcesフォルダにあるファイルをTextAssetを使用して読む場合はクローズしません。
各オブジェクトを配列格納
今回のテーマ(CSVファイルの読み込み)には関係ないのですが、この部分は画面上のオブジェクトを配列に格納しています。
TMPObj[0] = GameObject.Find("Input_Bougu"); // 配列に代入 名称入力枠
TMPObj[1] = GameObject.Find("Name"); // 〃 名称
TMPObj[2] = GameObject.Find("Kouka"); // 〃 効果
TMPObj[3] = GameObject.Find("Kaine"); // 〃 買値
TMPObj[4] = GameObject.Find("Urine"); // 〃 売値
TMPObj[5] = GameObject.Find("Soubi"); // 〃 装備可否表示欄
TMPObj[6] = GameObject.Find("Bikou"); // 〃 備考
TMPObj[7] = GameObject.Find("KoukaT"); // 〃 効果(項目名)
画面上のオブジェクトを使用する度に Find 探してもいいのですが、これらの項目は何度も使用するのであらかじめ変数に入れて置いた方が便利だったりします。
データ探索と画面表示
次は必要なデータを見つける。見つけたデータを画面表示する部分です。
武器欄、または防具欄に文字入力(Edit)して、それが終了した時に、以下のプログラムが走ります。
public void EditEndDisp() //
{ //
string InpTxt = TMPObj[0].GetComponent<TMP_InputField>().text; //【変数定義】防具名称 (名称入力欄から取得)
int bIx = Array.IndexOf(bName,InpTxt); //【変数定義】配列用添字(入力された名称と同じ防具名のindex取得)
//
if(bIx >= 0) // ■添字が0以上(見つからない場合は-1なので処理しない)
{ // │
string wSoubi = ""; // ├【変数定義】装備可否表示の文字列編集エリア
if(bSoubi1[bIx] >= 1){wSoubi += "ローレシア ";} // ├◆ローレシアの王子 装備可の場合は文字列編集エリアに代入
if(bSoubi2[bIx] >= 1){wSoubi += "サマルトリア ";} // ├◆サマルトリアの王子 装備可の場合は文字列編集エリアに代入
if(bSoubi3[bIx] >= 1){wSoubi += "ムーンブルク";} // ├◆ムーンブルクの王女 装備可の場合は文字列編集エリアに代入
// │
TMPObj[1].GetComponent<TextMeshProUGUI>().text = bName[bIx]; // ├ 画面表示 防具名称
TMPObj[2].GetComponent<TextMeshProUGUI>().text = bKouka[bIx] + ""; // ├ 〃 防具効果(文字列化)
TMPObj[3].GetComponent<TextMeshProUGUI>().text = bKaine[bIx] + ""; // ├ 〃 買値 (文字列化)
TMPObj[4].GetComponent<TextMeshProUGUI>().text = bUrine[bIx] + ""; // ├ 〃 売値 (文字列化)
TMPObj[5].GetComponent<TextMeshProUGUI>().text = wSoubi; // ├ 〃 装備可否
TMPObj[6].GetComponent<TextMeshProUGUI>().text = bBikou[bIx]; // ├ 〃 備考
TMPObj[7].GetComponent<TextMeshProUGUI>().text = "防御力"; // └ 〃 効果の項目名を防御力に変更
} //
} //
string InpTxt = TMPObj[0].GetComponent<TMP_InputField>().text;
この行ではTMPObj[0]オブジェクト、つまり武器または防具名称の入力欄に入力されたtext(=武器名または防具名)を InpTxt に代入します。
int bIx = Array.IndexOf(bName,InpTxt);
前の行で取得した武器名または防具名と同じモノがbName配列内にある場合、その要素番号(添字)を取得します。ない場合は-1が返答されます。
if(bIx >= 0) では前の行で取得した添字が0以上かどうかを判断しています。string wSoubi = ""; は装備可能のキャラを表示するための文字列変数です。
if(bSoubi1[bIx] >= 1) ここから3行は各キャラが装備できる場合、wSoubiにキャラがわかる様に文字列を追加しています。
TMPObj[1].GetComponent<TextMeshProUGUI>().text = bName[bIx];
ここから7行は画面表示をしています。bIxには入力された武器または防具の要素番号(添字)が入っているので、各配列を各オブジェクトのTextに入れているんですね。
変数配列が数字(int型)だった場合、空文字("")を追加することで文字列化しています。
おわりに
ここまで非常に長い記事にお付き合いいただきありがとうございます。
他のファイルから多くのデータを読み込んで扱うようになると大規模ゲームな感じがしてテンション上がりませんか?
もちろん、気持ちの問題だけでなく、やれる事が増えると作れるゲームも増える。するとアイディアも広がっていきますよね!
今回は武器と防具のスクリプトを2つに分けましたが、本来であれば1本で処理可能です。効率化を自分で考えてみるのも勉強になると思いますよ!
▼Unityでゲームを作るなら
▼Unity難しそう、もうちょっと簡単にゲーム作れない?
▼情報系学科の勉強に役立つマガジン