FC2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム » Unity »【Unity】【C#】テキストファイルの読み書きをする(リソース/ストレージ)

【Unity】【C#】テキストファイルの読み書きをする(リソース/ストレージ)  


 Unity では内部リソースからテキストファイルを読み込む方法が非常に簡単に用意されているが、それとは別に外部のリソース(ストレージ等)でテキストファイルを読み書きする方法も書いておこう。

 またついでに Android でプラグインを利用して読み書きする方法も紹介しておく。ちなみに Unity から C# で直接 SDカードに書き込もうとすると、アクセス拒否で失敗するが、プラグインを利用する場合は、SDカードにも書き込むことが可能だ。エクスプローラみたいなファイル選択も使えるので、ユーザーが自由にファイルの読み書きを行えるようなシステムを作るには役に立つだろう。

 ここでは C# スクリプト例はインスタンスメソッドとして書いておくが、static なライブラリとして利用したいなら、例外処理を throw などすれば良いと思う。とりあえず簡単な実装を書いておこう。自由に改造でもして使って欲しい。


(※) Unity 5.6.3p1 - 2018.1.8f1 / Windows10(x64) で確認



■リソースからテキストアセットを読み込む(Unity ビルトイン機能)

 ここでは Unity の機能を使って、アプリに内包したテキストファイルを読み込んでみよう。

 これは Unity のエディタ上であらかじめリソースとして持っておき、ランタイム時にロードする方法だ。Unity では「Resources」というフォルダを作っておくと、起動後にリソースとしてテクスチャやデータなどを読み込むことができる。ここにテキストファイルを置いておけば、「TextAsset」として簡単に扱える。それを利用して読み込んでみよう。

●リソースからテキストアセットを読み込む(メソッド定義)
using UnityEngine;
using UnityEngine.UI;

public string textAssetName = "Texts/テスト"; //拡張子はいらない
public Text displayText; //表示するUI-Text

//リソースからテキストアセットを読み込む
void LoadTextAsset(string name)
{
if (string.IsNullOrEmpty(name) || displayText == null)
return;

TextAsset textAsset = (TextAsset)Resources.Load(name, typeof(TextAsset));
if (textAsset != null)
displayText.text = textAsset.text;
else
Debug.Log("Not found TextAsset : " + name);
}

●使用例(メインでのコードなど)
using UnityEngine;

//ロードボタンのコールバックハンドラ
public void OnLoadTextAsset()
{
LoadTextAsset(textAssetName);
}

 読み込み先テキストには UI-Text(displayText)を用いているが、もちろん string 型の引数のメソッドを作って直接読み込んでも良い。これはあくまでも例なので、その辺りは用途に応じて書き換えて欲しい。

●「Resources」フォルダを作り、その配下にテキストファイル(UTF-8)をインポートしておく。

 テストするには UI-Button などを適当に配置し、「Button」の「OnClick()」にスクリプトの「OnLoadTextAsset()」を登録すれば良い。





●「テスト用スクリプトのアタッチ例


●ファイルの内容は任意(UTF-8)

※ランタイム時にログを見るにはプラグインライブラリのプレファブ「DebugConsole」をシーンに置き、コード中の Debug.Log() を XDebug.Log() に置き換えて下さい。また、インスペクタで「displayText」に「DebugConsole」以下の「Text」を登録します。



■ローカルストレージなどでテキストファイルの読み書きをする(C# スクリプト)

 次にパス(ファイル名)を指定してテキストファイル(UTF-8)を読み書きすることをやってみよう。

 例ではフォルダ(ディレクトリ)に「Application.persistentDataPath」を使っているが、これはプラットフォームによって変わるデフォルトの永続的な保存先となる。また、会社名(company name)やアプリ名(product name)でもフォルダ分けされる。詳しくは公式マニュアルで確認して欲しい。

(参考)Application.persistentDataPath

●ローカルストレージなどでテキストファイルの読み書きをする(メソッド定義)
using System;
using System.IO;
using System.Text;

//テキストをファイルから読み込む(行読み)
//※Android で SD カードから読み込みをするには、「AndroidManifest.xml」にパーミッション("READ_EXTERNAL_STORAGE" または "WRITE_EXTERNAL_STORAGE")が必要。
string LoadText(string path)
{
StringBuilder sb = new StringBuilder(1024); //※capacity は任意

try
{
using (StreamReader reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
sb.Append(line).Append("\n");
}
}
}
catch (Exception e)
{
Debug.Log(e.Message);
return null;
}

return sb.ToString();
}

//テキストをファイルに保存
//※Android で External Storage に書き込みをするには、「AndroidManifest.xml」にパーミッション("WRITE_EXTERNAL_STORAGE")が必要。
//※セキュリティ上、Unity から直接 SD カードには保存できない。
bool SaveText(string text, string path)
{
try
{
using (StreamWriter writer = new StreamWriter(path))
{
writer.Write(text);
writer.Flush();
writer.Close();
}
}
catch (Exception e)
{
Debug.Log(e.Message); //Access to the path "filename" is denied. → パーミッションが無い, 書き込みアクセス不可(SDカードなど)
return false;
}
return true;
}

●使用例(メインでのコードなど)
using UnityEngine;
using UnityEngine.UI;

public string filename = "test.txt";
public Text displayText; //表示するUI-Text

//ロードボタンのコールバックハンドラ
public void OnLoadClick()
{
if (string.IsNullOrEmpty(filename) || displayText == null)
return;

string path = Path.Combine(Application.persistentDataPath, filename); //プラットフォームによってパスは異なる

if (!File.Exists(path))
{
Debug.Log("Not found : " + path);
return;
}

string text = LoadText(path);
if (!string.IsNullOrEmpty(text))
displayText.text = text;
}

//セーブボタンのコールバックハンドラ
public void OnSaveClick()
{
if (string.IsNullOrEmpty(filename) || displayText == null)
return;

string path = Path.Combine(Application.persistentDataPath, filename); //プラットフォームによってパスは異なる

if (SaveText(displayText.text, path))
Debug.Log("Save to : " + path);
}

 テストするには UI-Button などを適当に配置し、「Button」の「OnClick()」にスクリプトの「OnLoadClick()」「OnSaveClick()」をそれぞれ登録すれば良い。
●UI-Button 配置とテスト用スクリプトのアタッチ例

●UI-Button のコールバック登録例

 読み書きするテキストには UI-Text(displayText)を用いているが、もちろん string 型の引数のメソッドを作って直接読み書きしても良い。これはあくまでも例なので、その辺りは用途に応じて書き換えて欲しい。

 なお、Android でSDカードに読み書きする場合は以下のパーミッションが必要になる。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />'

 パーミッションについての説明が必要なら以前の記事を参照して欲しい。


※ランタイム時にログを見るにはプラグインライブラリのプレファブ「DebugConsole」をシーンに置き、コード中の Debug.Log() を XDebug.Log() に置き換えて下さい。また、インスペクタで「displayText」に「DebugConsole」以下の「Text」を登録します。



■Android でファイル選択+テキストファイルの読み書きをする(プラグイン利用)

 ついでにプラグインに入っている「StorageLoadTextController」と「StorageSaveTextController」(~/FantomLib/Prefabs/System/ 以下。検索で探すと簡単)というテキストファイル読み書きの機能を使ってみよう。これら「~Controller」は Android 標準のファイル選択機能を使い、テキストファイルを読み込み・書き込みをしてくれるものだ。これら機能はプラグイン内部に実装されているので、自分でコードを書く部分は、機能呼び出しと結果受け取りだけで良い。

 ではまず、その機能呼び出しと結果受け取りのコードだけ書いてしまおう。名前は任意で良い。これらは各「~Controller」や UI-Button のコールバックハンドラとなる。

●コールバックハンドラ例(メインでのコードなど)
using UnityEngine;
using UnityEngine.UI;
using FantomLib;

public Text displayText; //表示するUI-Text

//読み込んだテキストを UI-Text に表示する
public void OnStorageLoad(string text)
{
if (string.IsNullOrEmpty(text) || displayText == null)
return;

displayText.text = text;
}

public StorageSaveTextController storageSaveTextController; //※インスペクタで登録

//UI-Text のテキストをファイルに保存する
public void OnStorageSave()
{
if (displayText == null || string.IsNullOrEmpty(displayText.text)) //※空は保存しない場合
return;

if (storageSaveTextController != null)
storageSaveTextController.Show(displayText.text);
}

//エラーステータス用コールバックハンドラ
public void OnError(string message)
{
Debug.Log(message);
}

 あとはヒエラルキーに「StorageLoadTextController」と「StorageSaveTextController」(~/FantomLib/Prefabs/System/ 以下。検索で探すと簡単)を置き、UI-Button など(※名前は任意)を Canvas に配置したら、インスペクタでコールバックを設定するだけだ。

●「StorageLoadTextController」と「StorageSaveTextController」を置く。テスト用スクリプトのアタッチ例。

●スクリプト(TextFileTest)へコールバック登録する
※または、StorageLoadTextController.OnResult に直接 UI.Text.text を登録しても良い。

●UI-Button から機能呼び出しをする


 あとはビルドするだけだが、プラグインを含む場合のビルドは「AndroidManifest.xml」が必要になる。その辺りは以前の記事にまとめてあるので参照して欲しい。もちろん「Build Settings...」にシーンを追加するのを忘れずに。

●ファイルの内容は任意(UTF-8)

※ランタイム時にログを見るにはプラグインライブラリのプレファブ「DebugConsole」をシーンに置き、コード中の Debug.Log() を XDebug.Log() に置き換えて下さい。また、インスペクタで「displayText」に「DebugConsole」以下の「Text」を登録します。


※この記事のUnityアセットはプラグインとして配布されています。


※とりあえず試してみたい方は、最新版をビルドした apk デモをダウンロードできます。動作確認にもどうぞ。


プラグインデモをダウンロード
(Google Drive を利用)


Android 4.2以上
※「提供元不明アプリのインストール」許可が必要です。






(関連記事)
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録


関連記事
スポンサーサイト



category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityリファレンス  Unityプラグイン  FantomPlugin  C# 
tb: 0   cm: --


トラックバック

トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/306-88dd4e05
この記事にトラックバックする(FC2ブログユーザー)

プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR