MRが楽しい

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

HoloLensでファイル変更イベントを検出する その3(HoloLensでの動作確認)

本日は Unity と HoloLens の技術調査枠です。
UWPアプリでファイル変更イベントを検出する方法をまとめます。

前回記事の続きです。
bluebirdofoz.hatenablog.com

サンプルコード

UnityEditor用コードとUWP用コードをまとめます。
それぞれの環境で以下のように動作します。
・UnityEditor環境
1.Assets/SteamingAssetsフォルダにTXTファイルが作成/削除/変更されたイベントを検出します。
2.イベントを検出すると、UnityEventで指定された関数を実行します。
・UWP環境
1.アプリケーションフォルダの LocalState フォルダに TXT ファイルが作成/削除/変更されたイベントを検出します。
2.イベントを検出すると、UnityEvent で指定された関数を実行します。
・FileChangeWatcher.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// UnityEvent を利用するため Events を追加
using UnityEngine.Events;

public class FileChangeWatcher : MonoBehaviour
{
    /// <summary>
    /// ファイル検出時実行処理
    /// </summary>
    [SerializeField, Tooltip("ファイル検出時実行処理")]
    private UnityEvent FileChangeEventUnityEvent;

    /// <summary>
    /// ファイル変更イベント検出フラグ
    /// </summary>
    private bool p_ChangedFlg;

    // ファイル監視の固有設定
#if WINDOWS_UWP
    /// <summary>
    /// 監視対象フォルダの指定
    /// </summary>
    private Windows.Storage.StorageFolder p_WatchStorageFolder = 
        Windows.Storage.ApplicationData.Current.LocalFolder;
    /// <summary>
    /// 監視対象ファイルの指定
    /// 全てのファイルを監視する場合はQueryOptionsで以下のList<string>を指定する
    /// ・"*"の単一のエントリを含む配列
    /// ・空の配列
    /// ・null
    // 複数の拡張子を監視する場合は.Addで監視対象の拡張子をリストに追加する
    /// </summary>
    private List<string> p_WatchTargets;

    /// <summary>
    /// ファイル監視の各種設定
    /// </summary>
    private void FileChangeWatch_Setting()
    {
        // 監視対象フォルダの指定
        // LocalStateフォルダを監視
        p_WatchStorageFolder = Windows.Storage.ApplicationData.Current.LocalFolder;

        // 監視対象ファイルの指定
        // ".txt"の拡張子を持つファイルを監視
        p_WatchTargets = new List<string> { ".txt" };
    }
#else
    /// <summary>
    /// 監視対象フォルダの指定
    /// </summary>
    private string p_WatchDir;
    /// <summary>
    /// 監視対象ファイルの指定
    /// ".txt"の拡張子を持つファイルを監視
    /// 全てのファイルを監視する場合は""を指定する
    /// 複数の拡張子を監視する場合は"*.txt|*.jpg"のように指定する
    /// </summary>
    private string p_WatchTarget;

    /// <summary>
    /// ファイル監視の各種設定
    /// </summary>
    private void FileChangeWatch_Setting()
    {
        // 監視対象フォルダの指定
        // Assets/StreamingAssetsフォルダを監視
        p_WatchDir = UnityEngine.Application.streamingAssetsPath;

        // 監視対象ファイルの指定
        // ".txt"の拡張子を持つファイルを監視
        p_WatchTarget = "*.txt";
    }
#endif

    /// <summary>
    /// 初期化処理
    /// </summary>
    private void Start()
    {
        // 検出フラグOFF
        p_ChangedFlg = false;

        // ファイル監視の各種設定
        FileChangeWatch_Setting();

        // ファイル監視初期化
        FileChangeWatch_Start();
    }

    /// <summary>
    /// 定期実行
    /// </summary>
    private void Update()
    {
        if (p_ChangedFlg)
        {
            // ファイル変更を検出すればUnityEvent実行
            FileChangeEventUnityEvent.Invoke();
            // 検出フラグをOFF
            p_ChangedFlg = false;
        }
    }

    /// <summary>
    /// ファイル変更時処理
    /// </summary>
    private void FileChangeEvent()
    {
        // 検出フラグONに変更する
        // UnityEventの実行はMainThreadで行う
        p_ChangedFlg = true;
    }

#if WINDOWS_UWP
    /// <summary>
    /// ファイル監視初期化
    /// </summary>
    private async void FileChangeWatch_Start()
    {
        // 監視を行うファイルの拡張子をリストに追加する
        List<string> fileTypeFilter = new List<string>();
        foreach(string watchTarget in p_WatchTargets)
        {
            fileTypeFilter.Add(watchTarget);
        }
        // ファイルリストのソート順とフィルターを指定する
        // OrderByNameではファイルは名前順にソートされる
        Windows.Storage.Search.QueryOptions queryOptions =
            new Windows.Storage.Search.QueryOptions
                (Windows.Storage.Search.CommonFileQuery.OrderByName, fileTypeFilter);

        // 監視を行うディレクトリに作成した QueryOptions を設定する
        // 戻り値として StorageFileQueryResult のインスタンスが取得できる
        Windows.Storage.Search.StorageFileQueryResult queryResult =
            p_WatchStorageFolder.CreateFileQueryWithOptions(queryOptions);

        // イベントを登録
        queryResult.ContentsChanged += QueryResult_Changed;

        // 監視を開始する
        Windows.Foundation.IAsyncOperation
            <System.Collections.Generic.IReadOnlyList
                <Windows.Storage.StorageFile>> fileList = queryResult.GetFilesAsync();
    }

    /// <summary>
    /// ファイル変更イベントコールバック
    /// </summary>
    private void QueryResult_Changed(Windows.Storage.Search.IStorageQueryResultBase sender, object args)
    {
        // ファイル変更イベント発生時の処理
        FileChangeEvent();
    }
#else
    /// <summary>
    /// ファイル監視インスタンス
    /// </summary>
    private System.IO.FileSystemWatcher fileSystemWatcher = null;

    /// <summary>
    /// ファイル監視初期化
    /// </summary>
    private void FileChangeWatch_Start()
    {
        // 監視用インスタンスの作成
        fileSystemWatcher = new System.IO.FileSystemWatcher();

        // 監視ディレクトリの指定
        fileSystemWatcher.Path = p_WatchDir;

        // 最終アクセス日時、最終更新日時、ファイル名を監視
        fileSystemWatcher.NotifyFilter =
            (System.IO.NotifyFilters.LastAccess
            | System.IO.NotifyFilters.LastWrite
            | System.IO.NotifyFilters.FileName);

        // 監視ファイルの指定
        fileSystemWatcher.Filter = p_WatchTarget;

        // イベントハンドラの追加
        // Changed: ファイル変更、Created: ファイル作成、Deleted: ファイル削除、Renamed: ファイル名変更
        fileSystemWatcher.Changed += new System.IO.FileSystemEventHandler(FileSystemWatcher_Changed);
        fileSystemWatcher.Created += new System.IO.FileSystemEventHandler(FileSystemWatcher_Changed);
        fileSystemWatcher.Deleted += new System.IO.FileSystemEventHandler(FileSystemWatcher_Changed);
        fileSystemWatcher.Renamed += new System.IO.RenamedEventHandler(FileSystemWatcher_Renamed);

        // 監視を開始する
        fileSystemWatcher.EnableRaisingEvents = true;
    }

    /// <summary>
    /// ファイル変更イベントコールバック関数
    /// </summary>
    private void FileSystemWatcher_Changed(System.Object source, System.IO.FileSystemEventArgs e)
    {
        // ファイル変更イベント発生時の処理
        FileChangeEvent();
    }

    /// <summary>
    /// ファイル名変更イベントコールバック関数
    /// </summary>
    private void FileSystemWatcher_Renamed(System.Object source, System.IO.RenamedEventArgs e)
    {
        // ファイル名変更イベント発生時の処理
        // 今回は処理無し
    }
#endif
}

その1と同様に Sphere オブジェクトにアタッチして、呼び出し関数としてオブジェクトの拡大関数を設定します。
f:id:bluebirdofoz:20190307092316j:plain

HoloLens(WindowsMR)プロジェクトの作成手順に従って、アプリを HoloLens にインストールします。
f:id:bluebirdofoz:20190307092327j:plain

アプリケーションをインストールすると、UserFolders/LocalAppData 配下にアプリケーションのディレクトリが生成されます。
配下の LocalState ディレクトリに txt ファイルをアップロードしてみます。
f:id:bluebirdofoz:20190307092338j:plain

ファイル追加に合わせて、オブジェクトの拡大関数が呼び出されました。
f:id:bluebirdofoz:20190307092347j:plain

ファイル変更イベントの発生タイミング

なお、LocalState ディレクトリに txt ファイルを配置しておくと、アプリ起動時とサスペンドからの回復時にもファイル変更イベントが発生するようです。