Unity側の値をCSVへ出力する方法についてです。
今回はUnity上での書き込みと、Android実機への書き込みも行います。
環境
- Windows10
- Unity Hub 2.4.5
- Unity 2020.3.25f1
- Android Studio 2020.3.1
Unity上での書き込み
まずはじめにUnity上でCSVファイルの書き込みを行います。
GameObjectの準備
まずはGameObjectの準備を行います。
以下の3つ作成いたします。
Cube > F
Cube > J
Empty > SaveCsv
適当に配置してOKです。
Scriptの作成
以下のように作成します。
using System.IO;
using System.Text;
using UnityEngine;
// csvに保存するためのコード
// SaveCsvへアタッチ
public class SampleSaveCsv : MonoBehaviour
{
// System.IO
private StreamWriter sw;
// Start is called before the first frame update
void Start()
{
// 新しくcsvファイルを作成して、{}の中の要素分csvに追記をする
sw = new StreamWriter(@"SaveData.csv", false, Encoding.GetEncoding("Shift_JIS"));
// CSV1行目のカラムで、StreamWriter オブジェクトへ書き込む
string[] s1 = { "F", "J", "time" };
/**
* s1の文字列配列のすべての要素を「,」で連結する
* @see https://docs.microsoft.com/ja-jp/dotnet/api/system.string.join?view=net-6.0#System_String_Join_System_String_System_String___
*/
string s2 = string.Join(",", s1);
/**
* s2文字列をcsvファイルへ書き込む
* @see https://docs.microsoft.com/ja-jp/dotnet/api/system.io.streamwriter.writeline?view=net-6.0#System_IO_StreamWriter_WriteLine_System_String_
*/
sw.WriteLine(s2);
}
// Update is called once per frame
void Update()
{
// Enterキーが押されたらcsvへの書き込みを終了する
if (Input.GetKeyDown(KeyCode.Return))
{
/**
* @see https://docs.microsoft.com/ja-jp/dotnet/api/system.io.streamwriter.close?view=net-6.0#System_IO_StreamWriter_Close
*/
sw.Close();
}
}
public void SaveData(string txt1, string txt2, string txt3)
{
string[] s1 = { txt1, txt2, txt3 };
string s2 = string.Join(",", s1);
sw.WriteLine(s2);
}
}
ちなみに「StreamWriterクラス」は、C#のクラスです。
公式ドキュメント
new StreamWriter
の第二引数にboolean値を渡していますが、
これは「true」だと同階層に同じファイル名があると既存のファイルへ新しい値だけを上書きします。
「false」だと値は全て新しくファイル自体を上書きします。
using System.IO;
using UnityEngine;
// Fキーを検出するコード
// Fへアタッチ
public class SampleF : MonoBehaviour
{
private float time;
GameObject saveCsv;
SampleSaveCsv sampleSaveCsv;
// Start is called before the first frame update
void Start()
{
/**
* SaveCsvのスクリプトを参照する
* @see https://docs.unity3d.com/ja/current/ScriptReference/GameObject.Find.html
*/
saveCsv = GameObject.Find("SaveCsv");
/**
* コンポーネントを返す
* @see https://docs.unity3d.com/ja/current/ScriptReference/GameObject.GetComponent.html
*/
sampleSaveCsv = saveCsv.GetComponent<SampleSaveCsv>();
}
// Update is called once per frame
void Update()
{
// Fキーが押されたら、csvに「F」と「いつ押されたか」という情報が書き加えられる
time += Time.deltaTime;
if (Input.GetKeyDown(KeyCode.F))
{
sampleSaveCsv.SaveData("F", " ", time.ToString());
}
}
}
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
// Jキーを検出するコード
// Jへアタッチ
public class SampleJ : MonoBehaviour
{
private float time;
GameObject saveCsv;
SampleSaveCsv sampleSaveCsv;
// Start is called before the first frame update
void Start()
{
/**
* SaveCsvのスクリプトを参照する
* @see https://docs.unity3d.com/ja/current/ScriptReference/GameObject.Find.html
*/
saveCsv = GameObject.Find("SaveCsv");
/**
* コンポーネントを返す
* @see https://docs.unity3d.com/ja/current/ScriptReference/GameObject.GetComponent.html
*/
sampleSaveCsv = saveCsv.GetComponent<SampleSaveCsv>();
}
// Update is called once per frame
void Update()
{
// Jキーが押されたら、csvに「J」と「いつ押されたか」という情報が書き加えられる
time += Time.deltaTime;
if (Input.GetKeyDown(KeyCode.J))
{
sampleSaveCsv.SaveData(" ", "J", time.ToString());
}
}
}
それぞれへアタッチ
先程、作成した3つのScriptを以下のようにアタッチします。
SampleF.cs > F
SampleJ.cs > J
SampleSaveCsv.cs > SaveCsv
PC上で動作確認
では、「Play」ボタンを押してキーボードの「FかJ」をタイピングしてみて下さい。
最後に「Enter」キーを押します。
プロジェクトフォルダ直下に「SaveData.csv」というファイルが作成され、以下のように1行目がタイトル、2行目からはどのボタンをいつ押したかが入力されています。
Android実機への書き出し
続いてはAndroidへの書き出しを行います。
今のままのコードでは書き出しはされません。
Android用にコードを記述する必要があります。
端末ごとに処理を分ける方法
詳細は以前書いたこちらの記事をご参考下さい。
SampleSaveCsvの修正
Start内を以下のように修正します。
void Start()
{
#if UNITY_ANDROID
// 新しくcsvファイルを作成して、{}の中の要素分csvに追記をする(Androidの処理)
string FilePath = @"/SaveData.csv";
sw = new StreamWriter(Application.persistentDataPath + FilePath, false, Encoding.GetEncoding("utf-8"));
#endif
#if UNITY_EDITOR
// 新しくcsvファイルを作成して、{}の中の要素分csvに追記をする(Unity上での処理)
sw = new StreamWriter(@"SaveData.csv", false, Encoding.GetEncoding("Shift_JIS"));
#endif
// CSV1行目のカラムで、StreamWriter オブジェクトへ書き込む
string[] s1 = { "F", "J", "time" };
/**
* s1の文字列配列のすべての要素を「,」で連結する
* @see https://docs.microsoft.com/ja-jp/dotnet/api/system.string.join?view=net-6.0#System_String_Join_System_String_System_String___
*/
string s2 = string.Join(",", s1);
/**
* s2文字列をcsvファイルへ書き込む
* @see https://docs.microsoft.com/ja-jp/dotnet/api/system.io.streamwriter.writeline?view=net-6.0#System_IO_StreamWriter_WriteLine_System_String_
*/
sw.WriteLine(s2);
}
解説をすると、Application.persistentDataPath
は機種依存のファイルパスで実機へ正しく書き込むために必要になります。
GameObjectの追加
以下のように適当にButtonを配置します。
AddButtonのScriptを作成
今回はButtonをクリックしたタイミングでデータを追加したいと思います。
using UnityEngine;
public class AddButton : MonoBehaviour
{
private float time;
GameObject saveCsv;
SampleSaveCsv sampleSaveCsv;
// Start is called before the first frame update
void Start()
{
saveCsv = GameObject.Find("SaveCsv");
sampleSaveCsv = saveCsv.GetComponent<SampleSaveCsv>();
}
public void onClick()
{
time += Time.deltaTime;
// テキストデータも適当です
sampleSaveCsv.SaveData("B", " ", time.ToString());
}
}
AddButtonへアタッチ
では、AddButtonへアタッチします。
- AddButtonオブジェクトへAddButton.csをアタッチ
- Inspectore > Button の「On Click()」へAddButton.csのイベントを設定(以下図参照)
SDカードへ書き込みをする場合は設定が必要
もしSDカードへ書き込みを行う場合、Unity側で少し設定が必要です。
Edit > Project setting > Player > Other Settings の下の方に
「Write Permisson」という項目があります。
こちらの項目を「External(SDCard)」へ変更します。
Android実機で動作確認
では、実機とPCを繋いで「Build And Run」をしてみましょう。
buildされたら、「Add Button」を何度かタップしてみます。
データの確認
データの確認ですが、保存先が端末によって異なります。
以下は一例になります。
「内部ストレージ/メモリーカード」 > 「Android」 > 「data」
このフォルダまで来るとインストールされているパッケージが沢山あると思います。
自分で作ったパッケージネームを探します。
パッケージネームはUnity側の、
Edit > Project Settings > Player > Other Settings の
「Package Name」から確認できます。
次のフォルダで「cache」と「files」があると思いますので、
「files」を選択します。
すると、「SaveData.csv」が保存されています。
これでAndroid実機へのcsv書き込みもできました。
まとめ
- ファイルの書き込みには StreamWriter を使う
- #if で端末の判定を行い実機によるpathを使い分ける
- Androidの保存先pathは Application.persistentDataPath を使う
以上ご拝読有難うございました。