【Unity】分岐可能!複数のcsvファイルをロードする方法

サムネイル
当サイトで紹介する商品・サービス等の外部リンクは、アフィリエイト広告を含む場合があります。
スポンサーリンク
本記事を読むと以下の実行ができます

画面クリックすると、複数のcsvを読み込む

Unityでゲームやアプリを開発する際にCSVファイル
シナリオやデータを簡単にロードできます。

特にシナリオ分岐や膨大なデータを管理する場合、
CSVを活用することで、プロジェクトの管理が飛躍的に楽になります。

本記事では、複数のCSVファイルをロードして、
それらをシーンや選択肢に応じて動的に切り替える方法を詳しく解説します。

本記事は次の人におすすめ
  • Unityで分岐シナリオ(選択肢)を実装したい
  • 複数のCSVファイルを簡単にロードしたい
  • シナリオ管理を効率化したい
  • テキストベースのノベルゲームを作成したい
  • Unityでのファイル管理を学びたい
スポンサーリンク

.Clear()

Clear()メソッドは、コレクション(リストや配列など)に格納されたデータを削除し、空にするために使用されます。

複数のcsvを扱う際には、CSVデータを格納するリストcsvDataをクリアして、
次にロードされるCSVファイルのデータが重複しないように管理しています。

基礎的なcsvファイルの読み込みを解説しています。
void LoadCSV(TextAsset csvFile)
{
    csvData.Clear(); // 前のデータをクリア
    Line = 0; // 行番号をリセット
    // CSVデータの読み込み処理
}

次のCSVファイルをロードする際に前のデータを一旦クリアすることで、
新しいデータが正常に読み込まれ、余計なバグを防ぐことができます。

csvファイルの読み込みを変更する

複数のCSVファイルを順に読み込む際に、
特定の条件やタイミングでファイルを変更したり、
次のCSVファイルに切り替える方法を学ぶことが重要です。

本スクリプトでは、index変数を使って現在のCSVファイルを追跡し、
すべての行を表示し終わったら次のファイルに自動的に切り替えます。

機能として、画面クリックでindex変数を進めます。

画面クリックしてcsvを進める方法を紹介しています。

ソースコード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using TMPro; // TextMeshProの追加

public class Multicsv : MonoBehaviour
{
    public TextMeshProUGUI DisplayText; // 表示するテキストUI
    public TextAsset[] csvFiles; // CSVファイル配列

    private List<string[]> csvData = new List<string[]>();
    private int Line = 0;
    private int index = 0;

    void Start()
    {
        if (csvFiles.Length > 0)
        {
            LoadCSV(csvFiles[index]); // 最初のCSVファイルをロード
            DisplayNextLine();
        }
        else
        {
            Debug.LogError("CSVファイルがアタッチされていません。");
        }
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0)) // クリックで次の行へ
        {
            DisplayNextLine();
        }
    }

    // CSVをロードするメソッド
    void LoadCSV(TextAsset csvFile)
    {
        csvData.Clear(); // 前のデータをクリア
        Line = 0; // 行番号をリセット

        StringReader reader = new StringReader(csvFile.text);

        while (reader.Peek() != -1)
        {
            string line = reader.ReadLine();
            csvData.Add(line.Split(',')); // CSVファイルの各行をリストに追加
        }

        Debug.Log(csvFile.name + "をロードしました");
    }

    void DisplayNextLine()
    {
        if (Line >= csvData.Count)
        {
            // 現在のCSVが終わったら次のCSVに切り替える
            index++;

            if (index < csvFiles.Length)
            {
                LoadCSV(csvFiles[index]); // 次のCSVファイルをロード
                DisplayNextLine(); // 次の行を表示
            }
            else
            {
                Debug.Log("すべてのCSVファイルを表示しました。");
            }
            return;
        }

        string[] lineData = csvData[Line];

        // テキストの表示
        DisplayText.text = lineData[0]; // テキスト内容は2列目にあると仮定
        Line++;
    }
}

解説

  • 名前空間

「System.Collections」:コレクションを扱うために必要な名前空間で、リストなどのデータ構造を利用するために使います。
「System.Collections.Generic」:ジェネリックコレクションを扱うために必要な名前空間で、型指定したリストなどを使うために使用します。
「UnityEngine」:Unityの基本的なクラスや関数(例えば、MonoBehaviourやDebug.Logなど)を使うために必要です。
「System.IO」:ファイルの入出力操作を行うための名前空間で、CSVファイルの内容を読み込むために使用しています。
「TMPro」:TextMeshProを使ってUIにテキストを表示するために必要な名前空間です。

textmeshproの使い方を紹介しています。
  • フィールド(メンバ変数)

「DisplayText」:ゲーム内に表示するテキストUIコンポーネントを参照します。
「csvFiles」:複数のCSVファイルを配列として保持し、順に読み込むために使います。
「csvData」:現在読み込まれているCSVファイルのデータを行ごとに保持するリストです。
「Line」:現在表示しているCSVデータの行番号を管理します。
「index」:現在読み込んでいるCSVファイルのインデックスを管理します。

  • Startメソッド

csvFilesにアタッチされたCSVファイルをロードし、1行目を表示します。
もしファイルがアタッチされていなければエラーメッセージを表示します。

  • Updateメソッド

ユーザーのクリック入力を検知します。
クリックされるとDisplayNextLineメソッドを呼び出して次の行を表示します。

マウスクリックについてまとめています。
  • LoadCSVメソッド

指定されたCSVファイルの内容をリストcsvDataに読み込みます。
リストcsvDataをクリアし、行番号をリセットします。

StringReaderを用いてCSVファイルの各行を読み込み、
それをカンマ区切りで分割してリストに格納します。

  • DisplayNextLineメソッド

現在の行番号に対応するCSVデータをUIに表示します。
すべての行を表示し終わったら次のCSVファイルに切り替えます。

全てのCSVファイルを表示し終わった場合、処理が終了します。

実演

画面上にテキストUIを配置します。

Resourcesフォルダー内にcsvを用意し、
これらをアタッチします。

UIやデータのアタッチ

クリックごとにUpdateメソッドが呼ばれ、
現在のCSVファイルのすべての行を表示し終わったら、次のCSVファイルをロードします。

すべてのCSVファイルを表示し終わった場合は、終了メッセージを表示します。

CSVファイルは、LoadCSVメソッドを使ってテキストとして読み込まれ、
その内容をカンマ区切りでリストに保存します。

選択肢で分岐させる(choice・move・do)

本記事のスクリプトは、csvファイルを順番に切り替えます。選択肢によって読み込むcsvを変えるには、csvの1列目に「命令」を書く方法が分かりやすいです。

1列目意味書き方の例
choice選択肢を出すchoice,逃げる,刀を抜く
movechoiceの次の行に置き、同じ列に行き先のcsv名を書くmove,1_1_逃走,1_2_戦う
do画面に何も出さず、別のcsvへ移るdo,2_戦闘
// 次の行を表示する前に、1列目の命令を確認する
void HandleLine(string[] lineData)
{
    // do:表示せずに別のcsvへ移る(行き先が循環しても固まらないよう、たどる回数に上限を付ける)
    int guard = 0;
    while (lineData[0] == "do" && guard++ < 16)
    {
        LoadCSV(Resources.Load<TextAsset>(lineData[1]));
        lineData = csvData[0];
    }

    if (lineData[0] == "choice")
    {
        string[] moveData = csvData[Line];   // choiceの次の行がmove
        ShowChoices(lineData, moveData);     // 選択肢のボタンを出す
        return;
    }

    DisplayText.text = lineData[0];
}

ShowChoicesは、選択肢のボタンを出す処理です。ボタンが押されたら、moveDataの同じ列に書いたcsv名をLoadCSVに渡します。

do行の行き先をたどる処理に上限が無いと、「Aのcsvがdo,B、Bのcsvがdo,A」のように行き先が循環していたとき、ループが終わらずにゲームが固まります。

move行は行き先の一覧なので、画面に表示しないようにします。クリックで1行ずつ進める作りだと、選択肢を出し損ねたときに「move,1_1_逃走,…」がそのままセリフとして出てしまいます。

著者の体験談
著者の体験談

自作のノベルゲームでは、この3つの命令だけで分岐と章の移動を書いています。move行が無い、選択肢が0個といったcsvの書き間違いがあっても止まらないよう、エラーログを出して普通の行として進める作りにしています。

まとめ

Unityで複数のCSVファイルをロードして分岐シナリオを作成する方法を解説しました。

Clear()メソッドを使って前のデータをクリアしたり、index変数で次のファイルを動的に切り替えることで、柔軟にファイル管理ができます。

このシステムを使うことで、分岐シナリオや大規模なデータを効率的に管理し、スムーズなゲーム体験を提供できます。

タイトルとURLをコピーしました