【Unity C#】コピペでできる! CSVファイルを読み込んで配列やリストに追加させる方法

【Unity C#】コピペでできる! CSVファイルを読み込んで配列やリストに追加させる方法

 ストーリーやステータスを追加する度にスクリプトに書き込んでますという方は必見です! コピペで実装できるCSVファイルを読み込む方法とリストに追加する方法を紹介していきます。メモ帳やエクセルで編集するだけでストーリーなどの情報を編集できるようになるのでぜひ活用してみてくださいね。

UnityにはResourcesフォルダの中身を読み込む機能がある

(型の名前) test = Resources.Load("ファイルの名前") as (型の名前);

 この1文を書くことで、Resourcesフォルダにおいてあるゲームオブジェクトやテキストなどを読み込むことができます。

事前準備

 今回はResourcesファルダの中にCSVというフォルダを作り、そこに敵の情報を管理するCSVファイルを置きます。

 こんな感じ→Recources/CSV/enemy.csv

 次に敵のステータスを管理する構造体とその構造体を格納するリストを用意します。

//敵を格納する構造体
    public struct ENEMY
    {
        public string name;
        public string info;
        //ステータス
        public float HP_now;
        public float HP;
        public float STR;
        public float INT;
        public float DEF;
        public float RES;

    }

//敵の構造体を格納するリスト
    public static List<ENEMY> enemy = new List<ENEMY>();

 これでOKです。

 最後に、メモ帳に敵の情報を”,”で区切って書いて保存し、拡張子をtxtからcsvに書き換えましょう。

 保存されたファイルを選択してF2を押すと簡単に名前や拡張子を変更できます。

 また、一行目は読み込まないようにしています。

名前,敵の説明,最大HP,物理攻撃力,魔法攻撃力,物理防御力,魔法防御力
敵1,敵1の説明,10,5,2,3,2
敵2,敵2の説明,6,1,7,4,8
ボス,ボスの説明,20,7,1,6,2

 余談ですが、メモ帳だと列が揃わずにズレたり、エクセルで開くと文字化けしたりする場合があります。その問題を解決できる無料でエクセルのような作業が可能なCSV編集ソフトがあるのでこちらを導入することを強くおすすめします。

 今回はenemy.csvというテキストファイルから、ENEMY構造体の要素を取得し、enemyというリストに加入させます。

実装

 CSVファイルからENEMY構造体をリストに加入させていき、最後にリストを返す関数です。初心者のためにコメント多めなのでお手数ですが不要なコメントは削除して使ってください。

 ポイントは3つです。

  • 一時入力用の構造体とリストがあること
  • for文の中で一番入力用の構造体に格納していく
  • 読み込んだデータはString型なので必要に応じて変換する
//ENEMY構造体のcsvファイルを読み込む
    public List<ENEMY> ENEMY_read_csv()
    {
        //一時入力用で毎回初期化する構造体とリスト
        ENEMY ene = new ENEMY();
        List<ENEMY> ene_list = new List<ENEMY>();

        
        //ResourcesからCSVを読み込むのに必要
        TextAsset csvFile;

        //読み込んだCSVファイルを格納
        List<string[]> csvDatas = new List<string[]>();

        //CSVファイルの行数を格納
        int height = 0;
 
        //for文用。一行目は読み込まない
        int i = 1;

        /* Resouces/CSV下のCSV読み込み */
        csvFile = Resources.Load("CSV/enemy") as TextAsset;
        //読み込んだテキストをString型にして格納
        StringReader reader = new StringReader(csvFile.text);
        while (reader.Peek() > -1)
        {
            string line = reader.ReadLine();
            // ,で区切ってCSVに格納
            csvDatas.Add(line.Split(','));
            height++; // 行数加算
        }
        for (i = 1; i < height; i++)
        {

            //[i]は行数。[0]~[6]は列数
            //csvDatasはString型なのでそのまま格納できる
            ene.name = csvDatas[i][0];
            ene.info = csvDatas[i][1];
            //String型をfloat型にして格納
            ene.HP = Convert.ToSingle(csvDatas[i][2]);
            ene.STR = Convert.ToSingle(csvDatas[i][3]);
            ene.INT = Convert.ToSingle(csvDatas[i][4]);
            ene.DEF = Convert.ToSingle(csvDatas[i][5]);
            ene.RES = Convert.ToSingle(csvDatas[i][6]);

            ene.HP_now = ene.HP;

            Debug.Log("敵を読み込んだ:" + ene.name);

            //戻り値のリストに加える
            ene_list.Add(ene);
        }
        return ene_list;
    }

コピペ化・使用例

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System;

public class GameSystem : MonoBehaviour
{


  //敵を格納する構造体
  public struct ENEMY
  {
    public string name;
    public string info;
    //ステータス
    public float HP_now;
    public float HP;
    public float STR;
    public float INT;
    public float DEF;
    public float RES;
  }

  //敵の構造体を格納するリスト
  public static List<ENEMY> enemy = new List<ENEMY>();

  
  void Start(){
    //敵リストに読み込んだ情報を反映
    enemy = ENEMY_read_csv();
  }



//ENEMY構造体のcsvファイルを読み込む
    public List<ENEMY> ENEMY_read_csv()
    {
        //一時入力用で毎回初期化する構造体とリスト
        ENEMY ene = new ENEMY();
        List<ENEMY> ene_list = new List<ENEMY>();

        
        //ResourcesからCSVを読み込むのに必要
        TextAsset csvFile;

        //読み込んだCSVファイルを格納
        List<string[]> csvDatas = new List<string[]>();

        //CSVファイルの行数を格納
        int height = 0;
 
        //for文用。一行目は読み込まない
        int i = 1;

        /* Resouces/CSV下のCSV読み込み */
        csvFile = Resources.Load("CSV/enemy") as TextAsset;
        //読み込んだテキストをString型にして格納
        StringReader reader = new StringReader(csvFile.text);
        while (reader.Peek() > -1)
        {
            string line = reader.ReadLine();
            // ,で区切ってCSVに格納
            csvDatas.Add(line.Split(','));
            height++; // 行数加算
        }
        for (i = 1; i < height; i++)
        {

            //[i]は行数。[0]~[6]は列数
            //csvDatasはString型なのでそのまま格納できる
            ene.name = csvDatas[i][0];
            ene.info = csvDatas[i][1];
            //String型をfloat型にして格納
            ene.HP = Convert.ToSingle(csvDatas[i][2]);
            ene.STR = Convert.ToSingle(csvDatas[i][3]);
            ene.INT = Convert.ToSingle(csvDatas[i][4]);
            ene.DEF = Convert.ToSingle(csvDatas[i][5]);
            ene.RES = Convert.ToSingle(csvDatas[i][6]);

            ene.HP_now = ene.HP;

            Debug.Log("敵を読み込んだ:" + ene.name);

            //戻り値のリストに加える
            ene_list.Add(ene);
        }
        return ene_list;
    }
}