HoloLens 開発を初めて思ったこと

こんにちは、つい最近 HoloLens 開発にを始めたばかりの長沢と申します。
いままでは、Web のサーバーサイド開発を主に行っていたため、HoloLens の開発では勝手がわからず戸惑うことも多いですが、優しいチームメンバーたちと一緒に楽しく開発をしています。

少し技術的な話になりますが、今日は、私が HoloLens 開発をはじめてみて、難しく感じたことを通して、少しでも開発の雰囲気が伝えられればと思います。
これから開発を始めようと思っている方の参考になれば幸いです。

まず、HoloLens アプリの基本的な開発環境ですが、大きく Unity と DirectX のどちらかを使います。弊社では基本的に Unity を使って開発をしています。
また、HoloLens 向けのアプリケーションは UWP (ユニバーサル Windows プラットフォーム) アプリケーションとして実装する必要があります。
そのため、Unity、UWP それぞれ向けの両方の便利な API を使えることになるのですが、裏を返すと Unity、UWP の両方のアプリ開発の知識が必要ということになってしまいます。

例えば、以下のようなコードでその雰囲気を感じられるのではないでしょうか。

using System;
using System;
using System.IO;
using UnityEngine;

#if WINDOWS_UWP
using System.Threading.Tasks;
using Windows.Storage;
#endif

public class MyScript : MonoBehaviour {
    // 初期化処理
    void Start()
    {
// UWP でしか実行できないので #if で囲む
#if WINDOWS_UWP
        // UWP のファイル操作 API が非同期メソッドとして実装されるため Task.Run を使用
        Task.Run(async () =>
        {
            // UWP の非同期メソッドの呼び出し (ファイルを読み込む処理)
            var folder =
                await KnownFolders.DocumentsLibrary.GetFolderAsync("Hoge");
            var file =
                await folder.GetFileAsync("hoge.bundle");
            var buffer = null;
            using (var stream = await file.OpenStreamForReadAsync())
            {
                // ファイルの内容を読み込み
                buffer = new byte[stream.Length];
                stream.Read(buffer, 0, (int)stream.Length);
            }

            // Unity のメインスレッドで Unity API を実行
            UnityEngine.WSA.Application.InvokeOnAppThread(() =>
            {
                AssetBundle assetBundle = AssetBundle.LoadFromMemory(buffer);
                
                ... // 以下は Unity 上での処理
                
            }, false);
        });
#else
        ... // Unity Editor 上で動かす際の処理
#endif
    }
}

上記のコードは、HoloLens 上に置いたファイルを Unity の AssetBundle として読み込む処理から一部を抜き出したコードです。

詳細については説明を省きますが、「#if WINDOWS_UWP」と「#else」に囲まれたコードの前半では UWP の非同期 API を使っています。非同期 API を使うために Task.Run() を使って別スレッドで処理を行っているところがポイントでしょうか。
また、後半部分では、Unity の API である AssetBundle.LoadFromMemory() を呼び出すために UnityEngine.WSA.Application.InvokeOnAppThread() を使って、Unity のメインスレッドで処理を行うようにしています。(この API は Unity のメインスレッド以外からは実行できないため)

あくまで、雰囲気を説明するためのサンプルではありますが、UWP と Unity の API を混ぜて書いている雰囲気をなんとなく感じていただけるのではないかと思います。

HoloLens の開発に慣れている方にとっては、そんなに戸惑うようなコードではないのかもしれませんが、私のような HoloLens 開発を始めたばかりの初心者にとっては、両方の制限を意識していないと、すぐに混乱してしまいます。どのような開発でも同じですが、まずは基本的な制限や API についての理解を深めて行くことが大事だなと感じました。

こういった、独自の難しさもありますが、反面新しく学ぶことが多いというのはとても楽しいことでもあります。
また、HoloLens 自体も比較的新しいデバイスということもあり、まだまだ自分たちで活用方法のアイディアを考えていける領域であり、そういった意味でもとてもやりがいがあります。

長い道のりになりそうですが、今後も HoloLens 開発者として、日々精進していこうと思います。

それではまた。