ENGINEER BLOG

ENGINEER BLOG

Unity×スマートグラスでARお絵描きをしてみよう

こんにちは。C&I統括本部テクノロジーイノベーションの樋口です。

以前、スマートグラスのアプリ開発に携わる機会があったのですが、せっかくなら個人でも何か作ってみたいな~と思い作成したスマートグラス内でお絵描きができるアプリをご紹介いたします。

👇ちなみにその際に開発したスマートグラスアプリのサイトもオープンしたので是非ご覧ください。

最新デバイス「スマートグラス」でバーチャル水族館体験 – ARCHグラス

はじめに


スマートグラスとは、メガネのような形状で、目の周辺に装着して使用するウェアラブルデバイスの1つ。
目の前に現れた画面で映像コンテンツを楽しんだり、音楽を聞いたりできる次世代のウェアラブル機器です。

img_01

最近では、Appleが発表した「Vision Pro」などが話題ですね。

今回は、Xreal light(旧:Nreal Light)というARグラスを使用して、
指で空中に絵を描けるアプリを作ってみました。

必要なもの


  • スマートグラス(XREAL light)
  • XREAL light対応のAndroidスマートフォン
  • NRSDK 1.10.2 (XREAL開発用のSDK)
  • Unity 2020.3.30f1

今回使用する、XREAL lightは基本的にスマートフォンに接続して使用されます。対応機種はこちら(https://www.xreal.com/jp/compatibility/)から確認できます。

ざっくり、開発用のSDK準備 → Unityでお絵描きアプリを作成 → XREAL lightで動かす
という流れで進めていきます。

Unityでお絵描きアプリを作成


  • まずは、UnityでARお絵描きするアプリを作成します。※Unityのインストールや画面の説明は省略させていただきます。
  • 以下、簡単に手順を紹介します。
    • 新規シーンを作成する
    • NRSDKをインポートする
    • お絵描き機能を作る(LineRenderer)
    • apkファイルをビルドする
    • スマートグラス上で動かす

1. 新規シーンを作成


  • まずば、新規プロジェクトを作成します。※UnityHubから作成しています。

    img_01

  • Unityのバージョン、テンプレートを選択、プロジェクト名を入力してプロジェクトを作成します。
    ※NRSDK は Unity 2018.4.X以降をサポートしているようです。
    ※テンプレートは3D、プロジェクト名は任意の名前です。

    img_01

  • プロジェクトを作成するとこのような画面が表示されます。

    img_01

  • あらかじめプラットフォームをAndroidに変更しておきます。

  • ステータスバーからFile > Build Settings...でビルド設定のウィンドウを開き、Platform欄のAndroidを選択して、Switch Platformボタンを押下して変更できます。

    img_01

2.NRSDKをインポート


XREAL開発用のSDKであるNRSDKをダウンロードして、先ほど作成したプロジェクトにインポートします。

  • NRSDKはXREALのDeveloperサイト(https://developer.xreal.com/)からダウンロードできます。

    img_01

  • ダウンロードの際に、ログインを求められるので、アカウントを作成してログインします。

    img_01

  • NRSDKForUnity_Release_1.10.2.unitypackage というファイルがダウンロードされるので、ダブルクリックします。(※記事作成時のSDKバージョンは1.10.2)

    img_01

  • Unity画面上に、Import Unity Package というウィンドウが開くので、チェックはそのまま import を押下してインポートします。

    img_01

  • Projectウィンドウで、Asset/NRSDK/Prefabs を開き、フォルダ内にある NRCameraRig と NRInput をHierarchyウィンドウにドラッグ&ドロップして、シーンに配置します。

    img_01

3. お絵描き機能を実装する


LineRenderer コンポーネント

  • 3D 空間に自由に線を引くために LineRenderer というコンポーネントを使って実装します。

  • ステータスバーからGameObject > Create Emptyで空のGameObjectを作成します。分かりやすいようにLineObjectなどに名前を変えておきます。

    img_01

  • 追加したLineObjectのInspectorウィンドウにあるAdd Componentをクリックすると検索窓が出るので、LineRendererを検索し、追加します。

    img_01

  • InspectorウィンドウでLineRendererの設定を下の画像のように変更します。※後ほど更新

    img_01

  • Projectウィンドウで、Assetフォルダ内にPrefabsフォルダを作成し、LineObjectをPrefabsフォルダにドラッグ&ドロップして、Prefab化します。

    img_01

スクリプトを作成

  • はじめに、NRSDKのソースコードに少し追記します。

    Assets/NRSDK/Scripts/input/HandsにあるHandStates.cs内のHandStateクラスに以下を追記します。

    public bool isPointing => currentGesture == HandGesture.Point;
    

    (人差し指を立てるポーズをすると線を描画できるようにしたいのですが、これを記載しないとうまく動作してくれませんでした。)

      // HandStates.cs
    
      // ソースコードを一部抜粋
        public class HandState
      {
          public readonly HandEnum handEnum;
          public bool isTracked;
          public Pose pointerPose;
          public bool pointerPoseValid;
          public bool isPinching => currentGesture == HandGesture.Pinch;
          public bool isPointing => currentGesture == HandGesture.Point; //ここに追記
          public HandGesture currentGesture;
          public float confidence;
          public readonly Dictionary jointsPoseDict = new Dictionary();
    
    
  • Projectウィンドウで、Assets/Scriptsフォルダを作成し、右クリック>Create>C# Scriptで新規スクリプトファイルを作成します。

    img_01

  • スクリプトに以下のように記述します。

    // DrawManager.cs
    
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using NRKernal;
    
    public class DrawManager : MonoBehaviour
    {
        //InspectorでLineObjectを設定する。
        [SerializeField] GameObject LineObject;
    
        //描画中のLineObject;
        private GameObject CurrentLineObject = null;
    
        // Use this for initialization
        void Start () {
    
        }
    
        // Update is called once per frame
        void Update () {
    
            //右手のHandStateを返す
            HandState handState = NRInput.Hands.GetHandState(HandEnum.RightHand);
            //人差し指の先端のPose(位置と 3D 空間での回転)を返す
            Pose handJoint = handState.GetJointPose(HandJointID.IndexTip);
    
            if(handJoint == null)
            {
                Debug.Log("handJoint not defiend");
                return;
            }
    
            //人差し指を立てるジェスチャー間(Pointing)
            if(handState.isPointing)
            {
                if(CurrentLineObject == null)
                {
                    //LineObjectを生成
                    CurrentLineObject = Instantiate(LineObject, new Vector3(0, 0, 0), Quaternion.identity);
                }
                //ゲームオブジェクトからLineRendererコンポーネントを取得
                LineRenderer render = CurrentLineObject.GetComponent();
    
                //LineRendererからPositionsのサイズを取得
                int NextPositionIndex = render.positionCount;
    
                //LineRendererのPositionsのサイズを増やす
                render.positionCount = NextPositionIndex + 1;
    
                //LineRendererのPositionsに人差し指の先端の位置情報を追加
                render.SetPosition(NextPositionIndex, handJoint.position);
            } 
            else//Pointingポーズ以外のとき
            {
                //描画中の線があったらnullにする
                if(CurrentLineObject != null)
                {
                    CurrentLineObject = null;
                }
            }
        }
    }
    
  • NRInputオブジェクトに作成したスクリプトをドラッグ&ドロップでアタッチします。

    img_01

  • NRInputオブジェクトを選択し、Inspectorウィンドウの以下の位置にLineObjectのPrefabを、ドラッグ&ドロップでスクリプト内の変数にPrefabを指定します。

    img_01

入力をハンドトラッキングに変更

  • Nreal Light のコントローラーを制御するNRInputコンポーネントの Input Source Type を Hands に変更します。

    img_01

  • Projectウィンドウの Assets > NRSDK>Prefabs > Hands にある、HRHand_R、HRHand_L プレハブをHierarchyウィンドウの NRInput > Right ゲームオブジェクトの下にドラッグ&ドロップします。

    img_01

  • 実装はこれで完了です!

Unity上で動作確認してみます

※Shiftキーを押しながら右クリックで、人差し指を立てたポーズを入力することができます。


Unity上では無事、動作しました!


4. apkファイルをビルドする


  • File > Build Settings… からビルドセッティング画面を開き、作業したシーンを登録しBuild And Runボタンでapkファイルで出力します。

    img_01

5. スマートグラス上で動かす


  • apkファイルをスマホに取り込んでインストールします。

  • Xreal lightではNebulaというアプリで作成したARお絵描きアプリを起動します。

  • スマホにGoogle Play StoreからNebulaアプリをインストールし、会員登録をします。
    下のような画面になれば、準備は完了です。

    play_01

それではスマートグラスでARお絵描きしてみます!


無事、スマートグラス上でも動作しました👏
Unity上で動作させた時よりも、線がガクガクしていますね・・・
スマホのスペック等も関係しているかもしれません。今後の改善点ですね💪

まとめ


はじめて一人でスマートグラス用のアプリを作ってみましたが、無事動くものができたのでほっとしています。。
今後は、描いた絵が動き出すなど、ただお絵描きするだけでなく次のアクションを実装してみたいですね。
(個人的には、魔法陣を描いて魔法を出してみたい笑)

最後までご覧いただき、ありがとうございました!