おもちゃラボ

Unityで遊びを作ってます

【Unity】ファイルの読み込みと書き込み方法3選

f:id:nn_hokuson:20201027151808p:plain:w650

Unityを使っていると、ファイルから読み込んだり、ファイルに書き込みをしたい場合が良くあります。C#にはファイルの読み書きをする方法がいくつか用意されていて微妙にややこしいので簡単にまとめておこうと思います。

TextAssetを使って読み込む

テキストファイルを読み込みたいときに一番簡単な方法です。スクリプト中でTextAsset変数を宣言しておき、インスペクタから読み込みたいテキストをセットします。

using UnityEngine;

public class Test : MonoBehaviour
{
    public TextAsset data;

    void Start()
    {
        Debug.Log(data.text);
    }
}

Fileクラスを使って読み書きする

Fileクラスを使うと、ファイルのオープンやクローズといった面倒なステップを踏まずにファイルの読み書きができます。一方で、シークや一部読み込みなどの細かい制御はできないので、その場合は次のStreamを使う必要があります。

using UnityEngine;
using System.IO;

public class Test : MonoBehaviour
{
    void Start()
    {
        // 書き込み
        string path = Application.persistentDataPath + "/test.txt";
        File.WriteAllText(path, "hoge");

        // 追記
        File.AppendAllText(path, "fuga");
        Debug.Log("Save at " + path);

        // 読み込み
        string data = File.ReadAllText(path);
        Debug.Log("Data is " + data);
    }
}

Fileクラスには、テキストデータの読み書きのためのWriteAllText, ReadAllTextの他に、バイナリデータを読み書きできるReadAllBytesとWriteAllBytesも用意されています。これらを使えば次のようにテクスチャの画像を保存することもできます。

using UnityEngine;
using System.IO;

public class Test : MonoBehaviour
{
    public Texture2D texture;

    void Start()
    {
        // テクスチャをバイト列にする
        byte[] data = texture.EncodeToPNG();

        // 画像の保存
        string path = Application.persistentDataPath + "/test.png";
        File.WriteAllBytes(path, data);
    }
}

Streamを使う

Unityで柔軟にファイルの読み書きをしたい場合はStreamReaderやStreamWriterを使います。StreamReaderには一行ずつ読み込むReadLineメソッドやファイル末尾まで一気に読み込むReadToEndメソッドが用意されています。また、StreamWriterの第2引数によって上書き保存か追記かを選択できます。

using UnityEngine;
using System.IO;

public class Test : MonoBehaviour
{
    void Start()
    {
        // 書き込み
        string path = Application.persistentDataPath + "/test.txt";
        bool isAppend = true; // 上書き or 追記
        using (var fs = new StreamWriter(path, isAppend, System.Text.Encoding.GetEncoding("UTF-8")))
        {
            fs.Write("ホップ\nステップ\nジャンプ");
        }

        // 一気に読み込む
        using (var fs = new StreamReader(path, System.Text.Encoding.GetEncoding("UTF-8")))
        {
            string result = fs.ReadToEnd();
            Debug.Log(result);
        }

        // 一行ずつ読み込む
        using (var fs = new StreamReader(path, System.Text.Encoding.GetEncoding("UTF-8")))
        {
            while (fs.Peek() != -1)
            {
                Debug.Log(fs.ReadLine());
            }

        }
    }
}

usingステートメントを使うことでファイルのクローズ忘れなどを防ぐことができます。usingステートメントについては「確かな力が身につくC#超入門 第2版」でも少し触れているので、あわせてご覧ください。