MRが楽しい

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

MRTKのMeshObserversでエディター上でSpatialMapの仮想メッシュを表示する

本日は MRTK の技術調査枠です。
MRTKのMeshObserversでエディター上でSpatialMapの仮想メッシュを表示する手順を記事にします。
f:id:bluebirdofoz:20210109221146j:plain

Mesh Observers

MRTK の Mesh Observers のプロファイルを設定することでエディター上で SpatialMap のメッシュを表示できます。
microsoft.github.io

サンプルプロジェクトの作成

MRTK 2.5をインポートして基本設定を行ったサンプルプロジェクトを作成しました。
f:id:bluebirdofoz:20210109221202j:plain

MRTK を使ったプロジェクトの基本設定の手順は以下の記事を参考にしてください。
bluebirdofoz.hatenablog.com

Mesh Observersの設定

MixedRealityToolkit オブジェクトの Inspector ビューを開き、[Copy & Customize]で新規プロファイルを作成します。
[Clone Profile]ダイアログが開くので、任意のプロファイル名を設定して[Clone]を実行します。
f:id:bluebirdofoz:20210109221218j:plain

[Spatial Awareness]タブを開き、[Enable Spatial Awareness System]にチェックを入れます。
f:id:bluebirdofoz:20210109221228j:plain

[SpatialAwarenessSystem]のプロファイルを[Clone]して新規プロファイルを作成します。
[Clone Profile]ダイアログが開くので、任意のプロファイル名を設定して[Clone]を実行します。
f:id:bluebirdofoz:20210109221236j:plain

これで[Spatial Awareness System Settings]の設定が編集できるようになります。
[Add Spatial Observer]をクリックして新しいオブザーバを追加します。
f:id:bluebirdofoz:20210109221245j:plain

追加したオブザーバの[Type]のプルダウンを開きます。
[Microsoft.MixedReality.Toolkit.SpatialObjectMeshObserver -> SpatialObjectMeshObserver]に設定します。
f:id:bluebirdofoz:20210109221253j:plain

これでエディター上でシーンを再生したときに、SpatialMap のメッシュが表示されるようになります。
f:id:bluebirdofoz:20210109221303j:plain

メッシュの差し替え

メッシュを差し替えたい場合は[ObjectMeshObserver]のプロファイルを[Clone]して新規プロファイルを作成します。
[Clone Profile]ダイアログが開くので、任意のプロファイル名を設定して[Clone]を実行します。
f:id:bluebirdofoz:20210109221312j:plain

これで[Object Mesh Observer Settings]の設定が編集できるようになります。
[Spatial Mesh Object]の欄に、メッシュとして表示したいプレハブを設定します。
f:id:bluebirdofoz:20210109221320j:plain

再びシーンを再生すると、差し替えたメッシュが表示されるようになります。
f:id:bluebirdofoz:20210109221330j:plain

このメッシュの表示はデフォルト設定ではエディター上でのみ実行される設定になっています。
f:id:bluebirdofoz:20210109221338j:plain

MRTKのglTFインポータで陰影が表示されない問題を回避する

本日は MRTK の技術調査枠です。
MRTKのglTFインポータの動的読み込みで HoloLens 実行時に陰影が表示されない問題を回避する手順を記事にします。

前提条件

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

MRTKのglTFインポータで陰影が表示されない問題

MRTKのglTFインポータを HoloLens2 上の動的読み込みで利用すると、以下のようにモデルの陰影が表示されない問題が発生します。
f:id:bluebirdofoz:20210108031527j:plain

この問題は以下の issue で管理されていますが、2021/01/08 現在、MRTK 2.5 で対応策は導入されていないようです。
github.com
github.com
github.com

2021/04/22:最新の issue を追記
github.com

原因

端的に言うとシェーダバリアントを最適化する仕組みにより、_DIRECTIONAL_LIGHT, _SPECULAR_HIGHLIGHTS の定義が無効化された状態でコンパイルされることが原因です。
microsoft.github.io

この問題は Editor 上では回避されるため、Editor のシーン再生でアプリを確認した場合は陰影が表示されます。
詳細は上記の issue に記述されています。
f:id:bluebirdofoz:20210108031949j:plain

回避策

_DIRECTIONAL_LIGHT, _SPECULAR_HIGHLIGHTS の定義が無効化されないシェーダに差し替えることで回避可能です。
一例として MRTKStandardShader を改変した以下のシェーダを利用してみました。
・MixedRealityStandardCullOffDefSpecular.shader

重要なのは 262 行目と 263 行目の以下の追記部分です。

            #define _DIRECTIONAL_LIGHT 1.0
            #define _SPECULAR_HIGHLIGHTS 1.0

_DIRECTIONAL_LIGHT と _SPECULAR_HIGHLIGHTS を有効な値で再定義しているため、シェーダバリアントの最適化で _DIRECTIONAL_LIGHT, _SPECULAR_HIGHLIGHTS の定義部分が無効化されなくなります。
再定義しているため、シェーダを Unity に取り込むとエラーが表示されますが、動作には問題ありません。
f:id:bluebirdofoz:20210108032321j:plain

後は読み込み完了後のモデルのシェーダをこのシェーダに差し替えるだけです。
前回記事のスクリプトを修正し、Renderer コンポーネントからマテリアルのシェーダを差し替える以下のスクリプトを作成しました。
・CustomGLBLoadTest.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// ファイル読み込み用
using System.IO;

// GLB読み込みライブラリの名前空間を追加
using Microsoft.MixedReality.Toolkit.Utilities.Gltf.Schema;
using Microsoft.MixedReality.Toolkit.Utilities.Gltf.Serialization;

// MRTKの名前空間を追加
using Microsoft.MixedReality.Toolkit.UI;
using Microsoft.MixedReality.Toolkit.Input;

// HoloLensフォルダ指定用
#if WINDOWS_UWP
using Windows.Storage;
#endif

public class CustomGLBLoadTest : MonoBehaviour
{
    /// <summary>
    /// 読み込みモデルファイル名
    /// </summary>
    [SerializeField, Tooltip("読み込みモデルファイル名")]
    private string p_LoadFileName;

    [SerializeField, Tooltip("再設定シェーダ")]
    private Shader p_ShaderOverride = null;

    /// <summary>
    /// 起動時処理
    /// </summary>
    void Start()
    {
        if (p_LoadFileName != null)
        {
            // ファイルパスを取得する
            string glbFilePath = Get3DObjectFilePath(p_LoadFileName);

            // glbファイルを読み込む
            AsyncLoadGLBByte(glbFilePath);
        }
    }

    /// <summary>
    /// 定期処理
    /// </summary>
    void Update()
    {
    }

    /// <summary>
    /// GLTF読み込みを実行する
    /// (バイト配列での読み込み例)
    /// </summary>
    /// <param name="filepath">ファイルパス</param>
    private async void AsyncLoadGLBByte(string filepath)
    {
        // Stopwatchの開始
        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
        stopwatch.Start();

        // 読み込みファイルのバイト配列を取得する
        byte[] modelByteData = GetFileAsByteArray(filepath);

        // バイト配列を指定して読み込み
        GltfObject gltfObject = GltfUtility.GetGltfObjectFromGlb(modelByteData);

        Debug.Log("ElapsedMilliseconds : " + stopwatch.ElapsedMilliseconds + " ms");

        try
        {
            // 非同期の読み込み処理を完了まで待機する
            await gltfObject.ConstructAsync();
        }
        catch (Exception e)
        {
            Debug.LogError($"GlbLoad failed - {e.Message}\n{e.StackTrace}");
            return;
        }

        Debug.Log("ElapsedMilliseconds : " + stopwatch.ElapsedMilliseconds + " ms");

        stopwatch.Stop();

        if (gltfObject != null)
        {
            // ゲームオブジェクトの参照を取得する
            GameObject loadedGlbObject = null;
            loadedGlbObject = gltfObject.GameObjectReference;

            if (loadedGlbObject != null)
            {
                // 子オブジェクトに設定してローカルトランスフォームを初期化する
                loadedGlbObject.transform.parent = this.transform;
                loadedGlbObject.transform.localPosition = Vector3.zero;
                loadedGlbObject.transform.localEulerAngles = Vector3.zero;
                loadedGlbObject.transform.localScale = Vector3.one;

                // ゲームオブジェクトへの再帰的な設定
                RecursionSettingModel(loadedGlbObject);

                Debug.Log("Import successful");
            }
        }
    }

    /// <summary>
    /// ゲームオブジェクトへの再帰的な設定
    /// </summary>
    /// <param name="a_Object"></param>
    private void RecursionSettingModel(GameObject a_Object)
    {
        foreach (Transform child in a_Object.transform)
        {
            // Rendererコンポーネントの参照を取得する
            Renderer targetRenderer = child.gameObject.GetComponent<Renderer>();

            if (targetRenderer != null && p_ShaderOverride != null)
            {
                // Rendererコンポーネントが存在すればシェーダを再設定する
                targetRenderer.material.shader = p_ShaderOverride;
            }

            // 再帰処理
            RecursionSettingModel(child.gameObject);
        }
    }

    /// <summary>
    /// Returns the contents of the specified file as a byte array.
    /// 指定されたファイルの内容をバイト配列として返します
    /// </summary>
    static byte[] GetFileAsByteArray(string filePath)
    {
        FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);

        BinaryReader binaryReader = new BinaryReader(fileStream);

        return binaryReader.ReadBytes((int)fileStream.Length);
    }

    /// <summary>
    /// 3Dフォルダ直下にある3Dモデルのファイルパスを取得する
    /// UnityEditor : Assets/StreamingAssetsフォルダ
    /// HoloLens : Objects3Dフォルダ
    /// </summary>
    /// <param name="filename">ファイル名</param>
    /// <returns></returns>
    public string Get3DObjectFilePath(string filename)
    {
#if WINDOWS_UWP
            // HoloLens上での動作の場合、Objects3D.Pathフォルダを参照する
            string directorypath = KnownFolders.Objects3D.Path;
#else
        // Unity上での動作の場合、Assets/StreamingAssetsフォルダを参照する
        string directorypath = UnityEngine.Application.streamingAssetsPath;
#endif
        return Path.Combine(directorypath, filename);
    }
}

前回記事と同様に、glb ファイルを読み込むオブジェクトにスクリプトをアタッチします。
[p_ShaderOverride]にモデル読み込み後、差し替えを行いたいシェーダを設定します。
f:id:bluebirdofoz:20210108032358j:plain

これで完了です。プロジェクトをビルドしてアプリを HoloLens2 に展開します。

動作確認

前回記事と同様、HoloLens2 上でアプリを起動して Object3D フォルダの glb ファイルの動的読み込みを試します。
以下の通り、陰影が表示された状態でモデルが表示されます。
f:id:bluebirdofoz:20210108032409j:plain

Mixed Reality OpenXRプラグインを使ってHolographic Remoting Playerに接続する その2(MRTKのインポート)

本日は HoloLens2 の小ネタ枠です。
XR Pluginを使ってHolographic Remoting Playerに接続する手順を記事にします。
f:id:bluebirdofoz:20210107092833j:plain

2021/10/19追記

本記事は Mixed Reality OpenXR plugin バージョン 0.1.1 時の記事になります。
2021/10/19 現在最新の Mixed Reality OpenXR plugin バージョン 1.1.1 では設定手順が本記事と一部異なります。
最新バージョンの手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com

前提条件

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

今回はプロジェクトに MRTK をインポートして Remoting Player でポジショントラッキングやハンドトラッキングを利用します。

Microsoft Mixed Realityサーバーの参照追加

前回記事に従って[Project Settings]を設定している場合、[PackageManager]のサーバの情報を一部修正します。
Microsoft Mixed Reality のサーバの[Scopes]に com.microsoft.spatialaudio の参照を追加して[Apply]します。

Name  : Microsoft Mixed Reality
URL   : https://pkgs.dev.azure.com/aipmr/MixedReality-Unity-Packages/_packaging/Unity-packages/npm/registry/
Scopes: com.microsoft.mixedreality
         com.microsoft.spatialaudio

f:id:bluebirdofoz:20210107092902j:plain

警告ダイアログが表示されます。[OK]を押して実行します。
f:id:bluebirdofoz:20210107092916j:plain

これで PackageManager から MRTK を参照する準備が整いました。
f:id:bluebirdofoz:20210107092928j:plain

MRTKパッケージの追加

次に PackageManager でパッケージのインポートを行います。
メニューから Windows -> PackageManager を選択します。
f:id:bluebirdofoz:20210107092943j:plain

[Package Manager]ダイアログが開きます。
[+]ボタンのプルダウンを開き、[Add package from git URL..]を選択します。
f:id:bluebirdofoz:20210107093001j:plain

入力欄が表示されるので、以下の通り、インポートしたいパッケージのURLを指定して[Add]ボタンでインポートします。
基礎パッケージのみ必須パッケージとなります。

基礎パッケージ    : com.microsoft.mixedreality.toolkit.foundation
ツールパッケージ  : com.microsoft.mixedreality.toolkit.tools
テストパッケージ  : com.microsoft.mixedreality.toolkit.testutilities
拡張パッケージ    : com.microsoft.mixedreality.toolkit.extensions
サンプルパッケージ: com.microsoft.mixedreality.toolkit.examples

f:id:bluebirdofoz:20210107093014j:plain

インポートが完了すると[MRTK Project Configurator]ダイアログが表示されるので[Apply]を実行します。
f:id:bluebirdofoz:20210107093024j:plain

再起動の要求ダイアログが表示されます。
[Apply]ボタンをクリックして Unity を再起動します。
f:id:bluebirdofoz:20210107093038j:plain

これで MRTK がインポートできました。
f:id:bluebirdofoz:20210107093051j:plain

シーンの設定

MRTK をインポートすると、メニューに[Mixed Reality Toolkit]が追加されます。
[Mixed Reality Toolkit -> Add to Scene and Configure..]を実行します。
f:id:bluebirdofoz:20210107093105j:plain

シーンに[MixedRealityToolkit]と[MixedRealityPlayspace]オブジェクトが追加されます。
f:id:bluebirdofoz:20210107093118j:plain

[MixedRealityToolkit]オブジェクトの[Inspector]ビューを開きます。
プロファイルのプルダウンを開き、[DefaultOpenXRConfigurationProfile]のプロファイルを指定します。
f:id:bluebirdofoz:20210107093129j:plain

これでシーンの設定が完了しました。

Tips

DefaultOpenXRConfigurationProfile のプロファイルは MRTK 2.5.2 以降から追加されています。

Editor実行時の背景設定

このままでも動作確認が可能ですが、UnityEditor でアプリを実行した場合は背景にスカイボックスが表示されます。
背景に黒の透過色を設定しておくことで、Remoting Player で HoloLens2 に投影した時、背景を透過させることができます。
f:id:bluebirdofoz:20210107093141j:plain

[DefaultOpenXRConfigurationProfile]のプロファイルを元に、[Copy & Customize]で新規プロファイルを作成します。
[Clone Profile]ダイアログが開くので、任意のプロファイル名を設定して[Clone]を実行します。
f:id:bluebirdofoz:20210107093154j:plain

更に[Camera]タブを開き、[CameraProfile]のプロファイルを[Clone]して新規プロファイルを作成します。
[Clone Profile]ダイアログが開くので、任意のプロファイル名を設定して[Clone]を実行します。
f:id:bluebirdofoz:20210107093205j:plain

これで[Display Settings]の設定が編集できるようになります。
UnityEditor での実行では[Opaque]の設定項目が参照されるため、[Skybox]が表示されています。
f:id:bluebirdofoz:20210107093215j:plain

[ClerFlags]を[Color]に変更して単一の背景色を設定します。
[Background Color]には黒の透過色を設定します。
f:id:bluebirdofoz:20210107093226j:plain

これで Editor 実行時の背景設定は完了です。

Holographic Remoting Playerに接続する

前回と同様にシーンを再生して、HoloLens2 で起動した Holographic Remoting Player に接続を行います。
f:id:bluebirdofoz:20210107093238j:plain

HoloLens2 側で UnityEditor 上で動作中のアプリケーションが表示され、ポジショントラッキングにカメラが追従すれば成功です。
f:id:bluebirdofoz:20210107093251j:plain

更にオブジェクトに[Object Manipulator]を設定すると、ハンドトラッキングも正常に動作することを確認できます。
f:id:bluebirdofoz:20210107093301j:plain

Mixed Reality OpenXRプラグインを使ってHolographic Remoting Playerに接続する その1(Mixed Reality OpenXRプラグインのインストール)

本日は HoloLens2 の小ネタ枠です。
Mixed Reality OpenXRプラグインを使ってHolographic Remoting Playerに接続する手順を記事にします。
f:id:bluebirdofoz:20210106025438j:plain

2021/10/19追記

本記事は Mixed Reality OpenXR plugin バージョン 0.1.1 時の記事になります。
2021/10/19 現在最新の Mixed Reality OpenXR plugin バージョン 1.1.1 では設定手順が本記事と一部異なります。
最新バージョンの手順は以下の記事を参照ください。
bluebirdofoz.hatenablog.com

前提条件

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

Mixed Reality OpenXRプラグイン

unity 2020.2 以降では HoloLens 2 および Windows Mixed Reality ヘッドセットの一連の機能をサポートした Mixed Reality OpenXR プラグインのパッケージが提供されています。
docs.microsoft.com

こちらのパッケージを使っても Holographic Remoting Player への接続が可能です。
以下にプラグインのインストール手順と Remoting Player の接続方法を記述します。

Microsoft Mixed Realityサーバーの登録

最初に PackageManager で参照するサーバーの登録を行います。
メニューから Edit -> Project Settings.. を選択します。
f:id:bluebirdofoz:20210106025504j:plain

[Project Settings]ダイアログが開くので[PackageManager]タブを開きます。
f:id:bluebirdofoz:20210106025512j:plain

[New Scoped Registry]の欄に以下のサーバーの設定を入力し、[Save]ボタンで登録します。

Name  : Microsoft Mixed Reality
URL   : https://pkgs.dev.azure.com/aipmr/MixedReality-Unity-Packages/_packaging/Unity-packages/npm/registry/
Scopes: com.microsoft.mixedreality

f:id:bluebirdofoz:20210106025523j:plain

これで参照サーバーの登録は完了です。
f:id:bluebirdofoz:20210106025534j:plain

Mixed Reality OpenXRプラグインの追加

次に PackageManager でパッケージのインポートを行います。
メニューから Windows -> PackageManager を選択します。
f:id:bluebirdofoz:20210106025543j:plain

[Package Manager]ダイアログが開きます。
[+]ボタンのプルダウンを開き、[Add package from git URL..]を選択します。
f:id:bluebirdofoz:20210106025552j:plain

入力欄が表示されるので com.microsoft.mixedreality.openxr のURLを指定して[Add]ボタンでインポートします。
f:id:bluebirdofoz:20210106025603j:plain

[Add]ボタンのクリックと共にインポートが開始します。
f:id:bluebirdofoz:20210106025612j:plain

インポートが完了すると、Assets フォルダに XR フォルダが追加されます。
f:id:bluebirdofoz:20210106025621j:plain

これで Mixed Reality OpenXR プラグインがインポートできました。

プラグイン構成の設定

再び[Project Settings]ダイアログを開き、[XR Plug-in Management]タブを開きます。
f:id:bluebirdofoz:20210106025632j:plain

Remoting Player を利用したい環境の[PC]、[UWP]タブそれぞれで構成の設定を行います。
[Initialize XR on Startup]にチェックを入れ、[OpenXR (Preview)]と[Microsoft HoloLens Feature Set]を有効にします。
f:id:bluebirdofoz:20210106025721j:plain
f:id:bluebirdofoz:20210106025732j:plain

[OpenXR (Preview)]の横に赤い警告アイコンが表示されることがあります。
この場合は、アイコンをクリックして表示されたダイアログで[Fix All]を実行します。
f:id:bluebirdofoz:20210106025743j:plain

問題が修正され、再起動の要求ダイアログが表示されます。
[Apply]ボタンをクリックして Unity を再起動すると問題が解消されます。
f:id:bluebirdofoz:20210106025756j:plain

警告アイコンが消えます。これで設定は完了です。
f:id:bluebirdofoz:20210106025806j:plain

Holographic Remoting Playerに接続する

同一ネットワークに接続した HoloLens2 で Holographic Remoting Player を起動します。
HoloLens2 のIPアドレスを確認します。
f:id:bluebirdofoz:20210106025815j:plain

[Project Settings]ダイアログを開き、[XR Plug-in Management -> OpenXR -> Features]タブを開きます。
f:id:bluebirdofoz:20210106025824j:plain

[Show All]を選択し、[Holographic Editor Remoting]にチェックを入れます。
[Settings]を開き、[Remote Host Name]に先ほど確認したIPアドレスを入力します。
これでエディターのシーンを再生すると同時に、Remoting Player の接続が実行されるようになります。
f:id:bluebirdofoz:20210106025836j:plain

動作確認

[再生]ボタンをクリックすると、ストリーミングが開始します。
f:id:bluebirdofoz:20210106025848j:plain

HoloLens2 側で UnityEditor 上で動作中のアプリケーションが表示されれば成功です。
f:id:bluebirdofoz:20210106025859j:plain

ただし、このままだとポジショントラッキングにカメラが追従しない問題が発生します。
Remoting Player でポジショントラッキングやハンドトラッキングを利用するには、更に MRTK のインポートと設定を行います。
bluebirdofoz.hatenablog.com

Unity 2020のGUI操作でUnityPackageManagerを使ってプロジェクトにMRTKをインポートする

本日は MRTK 2.5 の技術調査枠です。
Unity 2020 の GUI 操作のみで Unity Package Manager を使ってプロジェクトに MRTK をインポートする手順を記事にします。
f:id:bluebirdofoz:20210105223549j:plain

Unity 2020の変更点

以下の記事で manifest.json ファイルをテキストエディタで編集して MRTK 2.5 をインポートする手順を紹介しました。
bluebirdofoz.hatenablog.com

Unity 2020 からは ProjectSettings で PackageManaer の scopedRegistries を設定できるようになりました。
このため、以下の手順を行うことで、GUI 操作のみで MRTK のインポートを行うことができます。

Microsoft Mixed Realityサーバーの登録

最初に PackageManager で参照するサーバーの登録を行います。
メニューから Edit -> Project Settings.. を選択します。
f:id:bluebirdofoz:20210105223605j:plain

[Project Settings]ダイアログが開くので[PackageManager]タブを開きます。
f:id:bluebirdofoz:20210105223614j:plain

[New Scoped Registry]の欄に以下の Mixed Reality コンポーネントサーバーの設定を入力し、[Save]ボタンで登録します。

Name  : Microsoft Mixed Reality
URL   : https://pkgs.dev.azure.com/aipmr/MixedReality-Unity-Packages/_packaging/Unity-packages/npm/registry/
Scopes: com.microsoft.mixedreality
         com.microsoft.spatialaudio

f:id:bluebirdofoz:20210105223624j:plain

これで参照サーバーの登録は完了です。
f:id:bluebirdofoz:20210105223635j:plain

MRTKパッケージの追加

次に PackageManager でパッケージのインポートを行います。
メニューから Windows -> PackageManager を選択します。
f:id:bluebirdofoz:20210105223647j:plain

[Package Manager]ダイアログが開きます。
[+]ボタンのプルダウンを開き、[Add package from git URL..]を選択します。
f:id:bluebirdofoz:20210105223657j:plain

入力欄が表示されるので、以下の通り、インポートしたいパッケージのURLを指定して[Add]ボタンでインポートします。
基礎パッケージのみ必須パッケージとなります。

基礎パッケージ    : com.microsoft.mixedreality.toolkit.foundation
ツールパッケージ  : com.microsoft.mixedreality.toolkit.tools
テストパッケージ  : com.microsoft.mixedreality.toolkit.testutilities
拡張パッケージ    : com.microsoft.mixedreality.toolkit.extensions
サンプルパッケージ: com.microsoft.mixedreality.toolkit.examples

f:id:bluebirdofoz:20210105223707j:plain

[Add]ボタンのクリックと共にインポートが開始します。
f:id:bluebirdofoz:20210105223715j:plain

インポートが完了すると、Assets フォルダに MRTK フォルダが追加され、[MRTK Project Configurator]ダイアログが開きます。
f:id:bluebirdofoz:20210105223724j:plain

これで MRTK がインポートできました。

参考ページ

各パッケージの依存関係は以下のページを参照ください。
microsoft.github.io

HoloLens2でホロモンアプリを作る その3(HeadLookControllerでカメラの方を見る)

本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
f:id:bluebirdofoz:20210104214059j:plain

本記事はHeadLookControllerでカメラの方を見る設定です。

Head Look Controller

キャラクターの頭部ボーンのアニメーションをオーバライドしてカメラの方向を向けるアセットです。
ただし現在はアセットの更新がされておらず、アセットが非公開の状態になっています。
assetstore.unity.com

本記事では過去記事で取得したソースコードを元に設定を行いました。
bluebirdofoz.hatenablog.com

過去ソースコードを利用する場合、Unity 2018、2019 ではスクリプトを正常に動作させるため、一部コードを修正する必要があります。
nekuramakura.com

ソースコードの修正

Assets/HeadLookController/Script 配下の CursorHit.cs のコードを修正します。
f:id:bluebirdofoz:20210104214557j:plain

16行目~20行目のコードをコメントアウトするだけです。

using UnityEngine;
using System.Collections;

public class CursorHit : MonoBehaviour {
	
	public HeadLookController headLook;
	private float offset = 1.5f;
	
	// Update is called once per frame
	void LateUpdate () {
		if (Input.GetKey(KeyCode.UpArrow))
			offset += Time.deltaTime;
		if (Input.GetKey(KeyCode.DownArrow))
			offset -= Time.deltaTime;

		/* Unity 2019 環境では無効化する */
		// Ray cursorRay = Camera.main.ScreenPointToRay(Input.mousePosition);
		// RaycastHit hit;
		// if (Physics.Raycast(cursorRay, out hit)) {
		// 	transform.position = hit.point + offset * Vector3.up;
		// }

		headLook.target = transform.position;
	}
}

HeadLookControllerの設定

HeadLookController はキャラクターの頭部オブジェクトをカメラの方向に追従させます。
適当なオブジェクトに HeadLookController スクリプトをアタッチします。
f:id:bluebirdofoz:20210104214212j:plain

Inspector ビューから回転する部分や回転角度などの設定を行います。
[Segments]の[Size]から[Element]を追加して[Transform]で動く部位を指定できます。
[Override Animation]にチェックを入れることで指定部位のアニメーションを上書きします。
f:id:bluebirdofoz:20210104214221j:plain

今回、他の身体の部分のアニメーションを上書きしたくなかったので、頭部の部分のみをオーバーライドする設定を行いました。

CursorHitの設定

次に追従させたい対象オブジェクトを指定します。
今回はカメラの方向を向けたいので、カメラの子オブジェクトを用意して CursorHit スクリプトをアタッチしました。
f:id:bluebirdofoz:20210104214231j:plain

Inspector ビューの[Head Look]に先ほど HeadLookController を設定したオブジェクトを指定します。
f:id:bluebirdofoz:20210104214241j:plain

これで設定は完了です。

動作確認

シーンを再生して確認します。
ホロモンのアニメーションの首の部分が上書きされて常にカメラの方を向くようになりました。
f:id:bluebirdofoz:20210104214254j:plain

[MaxBendingAngle]の値を切り替えることでスムーズに振り向きの有効無効を切り替えることができます。
f:id:bluebirdofoz:20210104214303j:plain

切り替えスクリプト一例

コンポーネントの bool 値を切り替えることでスムーズに振り向きの有効無効を切り替えるスクリプトを作ってみました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// リアクティブプロパティ利用のため UniRx を使用
using UniRx;

namespace HMProject
{
    [RequireComponent(typeof(HeadLookController))]
    public class HeadLookSwitch : MonoBehaviour
    {
        [SerializeField, Tooltip("HeadLookの有効無効")]
        public BoolReactiveProperty isEnableReactive = new BoolReactiveProperty(true);

        /// <summary>
        /// HeadLookControllerの参照
        /// </summary>
        private HeadLookController headLookController;

        /// <summary>
        /// HeadLookControllerの最大角デフォルト設定
        /// </summary>
        private float[] defaultMaxBendingAngles;

        /// <summary>
        /// HeadLookControllerのアニメーション上書きのデフォルト設定
        /// </summary>
        private bool defaultOverrideAnimation;

        // Start is called before the first frame update
        void Start()
        {
            // 参照の取得
            headLookController = this.GetComponent<HeadLookController>();
            // デフォルトの最大角の取得
            int segmentnum = headLookController.segments.Length;
            if (segmentnum > 0)
            {
                defaultMaxBendingAngles = new float[segmentnum];
                for (int loop = 0; loop < segmentnum; loop++)
                {
                    defaultMaxBendingAngles[loop] = headLookController.segments[loop].maxBendingAngle;
                }
            }
            // デフォルトのアニメーション上書き設定の取得
            defaultOverrideAnimation = headLookController.overrideAnimation;
            // 有効無効切り替え時のリアクティブ処理を設定する
            isEnableReactive.Subscribe(
                onoff => ChangeMaxBendingAngle(onoff),
                () => ChangeMaxBendingAngle(true)
            );
        }

        /// <summary>
        /// 有効無効に合わせてHeadLookControllerの最大角を変更する
        /// </summary>
        /// <param name="onoff"></param>
        void ChangeMaxBendingAngle(bool onoff)
        {
            // 有効無効に合わせてHeadLookControllerの最大角を変更する
            int segmentnum = headLookController.segments.Length;
            if (segmentnum > 0)
            {
                for (int loop = 0; loop < segmentnum; loop++)
                {
                    float setValue = 0;
                    if (onoff)
                    {
                        setValue = defaultMaxBendingAngles[loop];
                    }
                    headLookController.segments[loop].maxBendingAngle = setValue;
                }
            }

            // アニメーションの上書き設定も変更する
            if (onoff)
            {
                headLookController.overrideAnimation = defaultOverrideAnimation;
            }
            else
            {
                headLookController.overrideAnimation = false;
            }
        }
    }
}

f:id:bluebirdofoz:20210104214313j:plain

HoloLens2でホロモンアプリを作る その2(歩きモーションと待機モーション)

本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
f:id:bluebirdofoz:20210103223314j:plain

歩きモーションと待機モーションの作成を行いました。

モーションの作成

以前作成したIKを活用してホロモンの歩き/走りモーションと待機モーションを作成しました。
モーション中に常に呼吸させるため、呼吸用のボーンを作成してモーションも作成しました。

歩きモーション

f:id:bluebirdofoz:20210103223337j:plain
f:id:bluebirdofoz:20210103223349j:plain

走りモーション

f:id:bluebirdofoz:20210103223400j:plain
f:id:bluebirdofoz:20210103223412j:plain

待機モーション

f:id:bluebirdofoz:20210103223424j:plain
f:id:bluebirdofoz:20210103223434j:plain

呼吸モーション

f:id:bluebirdofoz:20210103223446j:plain
f:id:bluebirdofoz:20210103223455j:plain