MRが楽しい

MRやVRについて学習したことを書き残す

hololensアプリでXML設定ファイルの操作を行う その1(読み込み)

本日は hololens の技術調査枠です。
アプリの設定を外部テキストファイルとして読み込みます。

今回の内容は以前調査済みの技術項目ですが、記事が半端で読み返し辛かったので再まとめの記事となります。
bluebirdofoz.hatenablog.com

確認用に新規プロジェクトを作成します。
f:id:bluebirdofoz:20171215031832j:plain

HoloToolkit を利用して、メニューから毎度お馴染み UWP アプリのビルド設定を行います。
f:id:bluebirdofoz:20171215031857j:plain

動作確認用にテキスト表示UIを用意して、まずは動作確認用の準備は完了です。
f:id:bluebirdofoz:20171215031905j:plain


では、XML設定ファイルの読み込みの仕組みを作ります。
Unity 上での動作と Hololens 上の動作で、参照ディレクトりを切り替える処理が必要です。
以下の通り、ファイルの置き場所を参照する関数を準備します。
・AppSettingManager.cs

/// <summary>
/// アプリ設定ファイル名(XML)
/// </summary>
private string p_AppSettingFileName = "settings.xml";

/// <summary>
/// アプリ設定ディレクトリパス
/// 実行環境によって参照ディレクトリを変更する
/// </summary>
private string SettingFileDirectoryPath()
{
    string directorypath = "";
#if WINDOWS_UWP
    // HoloLens上での動作の場合、LocalAppData/AppName/LocalStateフォルダを参照する
    directorypath = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
#else
    // Unity上での動作の場合、Assets/StreamingAssetsフォルダを参照する
    directorypath = UnityEngine.Application.streamingAssetsPath;
#endif
    return directorypath;
}

/// <summary>
/// アプリ設定ファイルパス(XML)
/// 実行環境によって参照ディレクトリを変更する
/// </summary>
private string XMLFilePath()
{
    string filepath = "";
    filepath = System.IO.Path.Combine(SettingFileDirectoryPath(), p_AppSettingFileName);
    return filepath;
}

Unity 側はファイルの置き場所として、"Application.streamingAssetsPath"を参照します。
これは Unity 上の「Asset/StreamingAssets」フォルダとなります。
Hololens 上では"Windows.Storage.ApplicationData.Current.LocalFolder.Path"を参照します。
これは Hololens 上の「LocalAppData/AppName/LocalState」フォルダとなります。


設定ファイルの読み書きにはインスタンスXml形式で入出力する XmlSerializer クラスを利用します。
また、前回検出した UWP アプリでは .CLose() メソッドや BinaryReader は使えない問題も対処しておきます。
・AppSettingManager.cs

/// <summary>
/// 設定ファイル情報
/// </summary>
private AppSettings p_AppSettings = new AppSettings();

/// <summary>
/// 設定ファイル構造クラス
/// </summary>
public class AppSettings
{
    public string Message;
}

/// <summary>
/// アプリ設定読み込み(XML)
/// </summary>
/// <returns>読み込み成否</returns>
public bool XMLRead()
{
    Debug.Log(this, "XMLRead");

    // 読み込み成否
    bool ret = false;

    // オブジェクトの型を指定して Serializer オブジェクトを作成する
    System.Xml.Serialization.XmlSerializer serializer;
    serializer = new System.Xml.Serialization.XmlSerializer(typeof(AppSettings));

    // ファイルの存在確認
    if (System.IO.File.Exists(XMLFilePath()) == true)
    {
        // 読み込みファイルを開く
        System.IO.StreamReader streamreader;
#if WINDOWS_UWP
        // 読み込みファイルを開く(UWPアプリではStreamReader(filepath)メソッドは使用不可)
        streamreader = new System.IO.StreamReader((System.IO.Stream)System.IO.File.OpenRead(XMLFilePath()));
#else
        // 読み込みファイルを開く
        streamreader = new System.IO.StreamReader(XMLFilePath(), new System.Text.UTF8Encoding(false));
#endif


        // XMLファイルから逆シリアル化する
        p_AppSettings = (AppSettings)serializer.Deserialize(streamreader);

#if WINDOWS_UWP
        // ファイルを閉じる(UWPアプリではClose()メソッドは使用不可)
        streamreader.Dispose();
#else
        // ファイルを閉じる
        streamreader.Close();
#endif

        // 読み込み成功
        ret = true;
    }

    return ret;
}


最後に Start 関数でこれらを利用して、設定読み込みを実施するコードを追加すればOKです。
・AppSettingManager.cs

/// <summary>
/// 初期化関数
/// </summary>
void Awake()
{
    // 設定ファイル読み込み
    bool isRead = XMLRead();
    if (isRead == false)
    {
        // 読み込みに失敗した場合はデフォルト値を設定
        p_AppSettings = new AppSettings();
    }
}

/// <summary>
/// 設定取得関数
/// </summary>
public AppSettings GetAppSettings()
{
    return p_AppSettings;
}

作成した AppSettingManager.cs をプロジェクトのゲームオブジェクトにアタッチします。
f:id:bluebirdofoz:20171215032045j:plain

更に、以下のようなアプリ設定の情報をテキストに反映するスクリプトを作成します。
・PanelTextController.cs

/// <summary>
/// テキスト出力ゲームオブジェクト
/// </summary>
public GameObject TextObject;

/// <summary>
/// テキストUI
/// </summary>
private UnityEngine.UI.Text p_Text;

/// <summary>
/// アプリ設定ゲームオブジェクト
/// </summary>
public GameObject AppSettingsObject;

/// <summary>
/// アプリ設定マネージャ
/// </summary>
private AppSettingManager p_AppSettingManager;

/// <summary>
/// 初期化関数(Start)
/// </summary>
void Start () {
    // テキストUI参照の取得
    p_Text = TextObject.GetComponent<UnityEngine.UI.Text>();
    // アプリ設定マネージャの取得
    p_AppSettingManager = AppSettingsObject.GetComponent<AppSettingManager>();
    // アプリ設定の取得文字列をテキストに反映
    p_Text.text = p_AppSettingManager.GetAppSettings().Message;
}

作成したスクリプトをプロジェクトに配置して、参照するゲームオブジェクトを設定します。
f:id:bluebirdofoz:20171215032110j:plain

最後に Assets/StreamingAssets ディレクトリを作成し、以下のXMLファイルを配置します。
・settings.xml

<?xml version="1.0" encoding="utf-8"?>
<AppSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Message>Hello World</Message>
</AppSettings>

f:id:bluebirdofoz:20171215032120j:plain


以上の状態でアプリを実行してみると……。
f:id:bluebirdofoz:20171215032129j:plain
表示メッセージが XML 設定ファイルにある「Hello World」の文字列に変わりました。成功です。

続けて HoloLens 上での動作についても確認します。
アプリを HoloLens にインストールした後、DevicePortal で LocalAppData/(AppName)/LocalState のフォルダにXMLファイルを配置します。
f:id:bluebirdofoz:20171216102210j:plain

アプリを起動すると……。
f:id:bluebirdofoz:20171216102221j:plain
メッセージが表示されました。成功です。

ここまで情報を残して置けば未来の自分も情報の掘り返しに困るまい。