本日は HoloLens2 の技術調査枠です。
XmlSerializer クラスを使ってアプリ情報をXMLファイルに読み書きします。
XmlSerializer
オブジェクトから XML ドキュメントへのシリアル化および XML ドキュメントからオブジェクトへの逆シリアル化を実行します。
docs.microsoft.com
サンプルプロジェクト
以下のサンプルプロジェクトを作成しました。
アプリケーションの起動時間を XML ファイルに保存し、アプリを終了しても再起動時に以前の起動時間を確認できます。
XmlSerializer クラスを使った XML ファイルの読み書きを行うクラスを作成しました。
・DataController.cs
using System.Collections; using System.Collections.Generic; using System; using UnityEngine; // クラス名を別名でまとめて管理する using CUSTOMTYPE = DataFormat; public class DataController : MonoBehaviour { /// <summary> /// 保持データ /// </summary> [SerializeField, Tooltip("保持データ")] private CUSTOMTYPE p_Data; /// <summary> /// 保存ファイル名 /// </summary> [SerializeField, Tooltip("保存ファイル名")] private string p_FileName; /// <summary> /// データを読み込む /// </summary> public CUSTOMTYPE LoadData() { return XMLRead(p_FileName); } /// <summary> /// データを書き込む /// </summary> public void SaveData(CUSTOMTYPE a_Data) { XMLWrite(p_FileName, a_Data); } /// <summary> /// データ読み込み(XML) /// </summary> /// <returns>読み込み成否</returns> private CUSTOMTYPE XMLRead(string a_FileName) { // 読み込み成否 bool ret = false; CUSTOMTYPE resultData = null; // オブジェクトの型を指定して Serializer オブジェクトを作成する System.Xml.Serialization.XmlSerializer serializer; serializer = new System.Xml.Serialization.XmlSerializer(typeof(CUSTOMTYPE)); // ファイルの存在確認 if (System.IO.File.Exists(XMLFilePath(a_FileName)) == true) { // 読み込みファイルを開く System.IO.StreamReader streamreader; #if WINDOWS_UWP // 読み込みファイルを開く(UWPアプリではStreamReader(filepath)メソッドは使用不可) streamreader = new System.IO.StreamReader((System.IO.Stream)System.IO.File.OpenRead(XMLFilePath(a_FileName))); #else // 読み込みファイルを開く streamreader = new System.IO.StreamReader(XMLFilePath(a_FileName), new System.Text.UTF8Encoding(false)); #endif // XMLファイルから逆シリアル化する resultData = (CUSTOMTYPE)serializer.Deserialize(streamreader); #if WINDOWS_UWP // ファイルを閉じる(UWPアプリではClose()メソッドは使用不可) streamreader.Dispose(); #else // ファイルを閉じる streamreader.Close(); #endif // 読み込み成功 ret = true; } return resultData; } /// <summary> /// データ書き込み(XML) /// </summary> private bool XMLWrite(string a_FileName, CUSTOMTYPE a_Data) { Debug.Log("XMLWrite"); // 書き込み成否 bool ret = false; // オブジェクトの型を指定して Serializer オブジェクトを作成する System.Xml.Serialization.XmlSerializer serializer; serializer = new System.Xml.Serialization.XmlSerializer(typeof(CUSTOMTYPE)); // ディレクトリの存在確認 if (System.IO.Directory.Exists(SettingFileDirectoryPath()) == true) { // 書き込みファイルを開く System.IO.StreamWriter streamwriter; #if WINDOWS_UWP // 書き込みファイルを開く(UWPアプリではStreamWriter(filepath)メソッドは使用不可) streamwriter = new System.IO.StreamWriter((System.IO.Stream)System.IO.File.OpenWrite(XMLFilePath(a_FileName))); #else // 書き込みファイルを開く streamwriter = new System.IO.StreamWriter(XMLFilePath(a_FileName), false, new System.Text.UTF8Encoding(false)); #endif // シリアル化してXMLファイルに保存する serializer.Serialize(streamwriter, a_Data); #if WINDOWS_UWP // ファイルを閉じる(UWPアプリではClose()メソッドは使用不可) streamwriter.Dispose(); #else // ファイルを閉じる streamwriter.Close(); #endif // 書き込み成功 ret = true; } return ret; } /// <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 a_FileName) { string filepath = ""; filepath = System.IO.Path.Combine(SettingFileDirectoryPath(), a_FileName); return filepath; } }
今回はデータの定義として以下のクラスを定義しています。
・DataFormat.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; /// <summary> /// 保存データフォーマット /// </summary> [Serializable] public class DataFormat { public List<TimeData> MarkDataList; } /// <summary> /// 記録時刻 /// </summary> [Serializable] public class TimeData { /// <summary> /// ID /// </summary> public string IdText; /// <summary> /// タイムスタンプ /// </summary> public DateTime DateTimeStamp; }
この XML ファイルへの読み書きを利用して、以下のスクリプトで起動時刻の保存、テキストへの表示を行います。
・LaunchTimeRecorder.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System; public class LaunchTimeRecorder : MonoBehaviour { /// <summary> /// テキスト表示UI /// </summary> [SerializeField, Tooltip("テキスト表示UI")] private Text p_MessageText; /// <summary> /// 保存データ参照 /// </summary> [SerializeField, Tooltip("保存データ参照")] private DataController p_DataController; // Start is called before the first frame update void Start() { // 履歴データを読み込む DataFormat historyData = p_DataController.LoadData(); if (historyData == null) { historyData = new DataFormat(); historyData.MarkDataList = new List<TimeData>(); } // 起動時刻を記録する TimeData launchData = new TimeData(); launchData.IdText = "Launch_" + historyData.MarkDataList.Count.ToString(); launchData.DateTimeStamp = DateTime.Now; historyData.MarkDataList.Add(launchData); // UIにデータを表示する string message = ""; foreach(TimeData timeData in historyData.MarkDataList) { message += timeData.IdText + " : " + timeData.DateTimeStamp.ToString() + Environment.NewLine; } p_MessageText.text = message; // 履歴データを書き込む p_DataController.SaveData(historyData); } }
これらのスクリプトを以下の通り、シーンに設定しました。
Unityエディター上での動作確認
Unityエディター上で[再生]ボタンを押してシーンを再生してみます。
XML ファイルは Assets/StreamingAssets フォルダ配下に保存され、[再生]を行う度に起動時間が保存されていきます。
HoloLens2上での動作確認
HoloLens2 にアプリをデプロイして動作を確認してみます。
こちらでもアプリケーションを起動するたびに起動時間が保存され、パネルUIに表示されます。
HoloLens2 上の動作では XML ファイルはアプリケーションフォルダの LocalState に保存されます。
参考ページ
本記事は以下の記事の内容を HoloLens2 で改めて動作確認を行い、再編した記事です。
bluebirdofoz.hatenablog.com
bluebirdofoz.hatenablog.com