Share via


在 Unity 中移動平臺模式

移動平臺模式可讓HoloLens 2在移動平臺上正常運作,例如船、油平臺和其他車輛。

深入瞭解移動平臺模式

概觀說明

若要讓混合實境系統正常運作,必須追蹤與環境相對的頭戴式裝置。 此相對追蹤可讓圖形轉譯,讓頭戴式裝置的使用者在環境中受到穩固鎖定。 追蹤通常是藉由結合使用向外外觀相機和慣性測量單位 (IMU) 計算的姿勢來達成。 當環境處於慣性參考框架時,這個方法可正常運作。 一般會忽略小型效果,例如運動。

當環境不在慣性參考框架中時,一般前端追蹤系統將會失敗。 移動平臺模式功能可藉由考慮相對於慣性框架的環境動作來解決此問題。 因此,當處於移動平臺模式時,HoloLens 2即使環境是亮起的出貨,也可以轉譯看起來固定在環境的全像投影!

如何啟用移動平臺模式?

為了啟用各種使用案例,已提供各種方法來啟用移動平臺模式。 請務必仔細考慮要選擇的方法。 要詢問的重點是:誰知道HoloLens 2目前是否在移動平臺內? 如需範例,請參閱下表:

誰知道 HL2 是否在移動平臺中 設定移動平臺模式的最佳方法 優點 費用
系統管理員 行動裝置管理 使用者不需要參與。 任何應用程式都會在沒有修改的情況下運作。 裝置可以受到保護,以免進入不正確的模式。 使用者和應用程式無法變更模式。
使用者 設定應用程式 使用者通常最瞭解使用裝置的時機和位置。 任何應用程式都會在沒有修改的情況下運作。 使用者可能不知道模式存在。
應用程式 請使用本文中所述的 SDK。 使用案例特定提示可用來在環境無法事先得知時交換模式。 移除使用者必須做出此決定,並在設定中變更模式的需求。 設計不佳的應用程式可能會提供非常不良的體驗,並讓裝置處於非預期模式。

移動平臺模式的最佳做法

主體 描述
尊重使用者選擇 您應該在變更其模式之前提供使用者選擇,您應該繼續遵守該應用程式執行時間的該選擇
提供警告給使用者 避免在應用程式的開始/繼續時立即變更模式。 這會顯示不佳的使用者體驗,因為使用者可能不知道裝置遺失追蹤的原因。
最小化變更模式 變更移動平臺模式設定時,裝置將會失去追蹤,導致負面的使用者體驗。 因此,建議您將變更模式的頻率降到最低。 在理想情況下,只有在裝置從固定環境轉換為移動環境時,才會變更模式,反之亦然。
如果不確定環境,請使用移動平臺模式 移動平臺模式可以在固定環境中運作,以及移動平臺模式。 一般追蹤演算法只能在固定環境中運作,因此如果您不確定環境是否正在移動,選擇 [移動平臺模式] 可能是更安全的選擇。
請勿在已知的固定環境中使用移動平臺模式 移動平臺模式在固定環境中執行效能低於標準模式。 雖然大部分的使用者都會注意到這一點,但這是很小的降低。
考慮將裝置留在哪個模式 此 SDK 可讓開發人員設計在裝置開機時健全的體驗。 請考慮裝置下次開機時是否在移動平臺上,並讓裝置保持適當的模式。

哪裡可以取得 SDK?

移動平臺 SDK 支援 C# 和 C++ 的語言投影,可讓開發人員開發 Win32 或 UWP 平臺的應用程式。 使用Mixed Reality 功能工具下載並安裝 SDK。

如何?使用此 SDK

安裝 SDK 之後,您可以設定腳本以使用 MovingPlatformManger,如下所示:

// Top of file
using Microsoft.MixedReality.MovingPlatform;
// Code body
m_movingPlatformManager = new MovingPlatformManager();

讀取目前模式

模式的目前值可以讀取,如下所示:

MovingPlatformMode currentMode = m_movingPlatformManager.Mode;

MovingPlatformMode 是定義如下的列舉:

public enum MovingPlatformMode
{
    Standard,                // The legacy mode that devices use out-of-the-box.
    MovingPlatformOptimized  // Allows tracking on moving platforms.
}

沒有移動平臺模式的裝置,例如 VR 裝置和 HoloLens 1,一律會傳回「標準」。

設定模式

您可以設定 [移動平臺模式] 值,如下所示:

bool success = m_movingPlatformManager.TrySetMode(MovingPlatformMode.MovingPlatformOptimized);

如果裝置模式現在符合要求的模式,TrySetMode 會傳回 true。 如果模式已處於預期狀態,則不會執行任何動作,且裝置不會遺失追蹤。

模式變更的回呼

有時候,知道另一個應用程式或使用者是否已變更移動平臺模式值會很有用。 您可以執行此動作,如下所示。

// Code Body
m_movingPlatformManager.ModeChanged += CallbackOnMPMChanged;
...
void CallbackOnMPMChanged(object sender, MovingPlatformEventArgs args)
{
    movingPlatformModeChanged = true;
    movingPlatformModeValue = args.ModeEntered;
}
...
void Update()
{
    // It's not reccomended to do work in the callback.
    if (movingPlatformModeChanged)
    {
        movingPlatformModeChanged = false;
        // Do some work
    }
}

檢查模式是否可設定

有時候,在嘗試變更模式之前,知道模式是否可設定是有用的。 例如,如果您想要知道是否有任何值詢問使用者其喜好設定。 您可以使用 IsSetModeSupported 函式來找到移動平臺模式是否可設定:

bool supported = m_movingPlatformManager.IsSetModeSupported();

如果裝置可以變更模式,則此函式會傳回 true,如果無法變更則傳回 false。 此函式會考慮行動裝置裝置管理 (MDM) 原則。 例如,如果 MDM 強制 MovingPlatformMode 為 「On」,則此函式會傳回 false。

示範腳本

此腳本會在一個位置顯示 SDK 的所有重要元素。 此範例不會遵循上述的最佳做法。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.MixedReality.MovingPlatform;
using System;

public class MovingPlatformDemo : MonoBehaviour
{
    public GameObject cube; // A simple cube to display colors.
    private MovingPlatformManager m_movingPlatformManager;
    private Renderer cubeRenderer;
    private bool movingPlatformModeChanged;
    private MovingPlatformMode movingPlatformModeValue;

    // Start is called before the first frame update
    void Start()
    {
        m_movingPlatformManager = new MovingPlatformManager();
        cubeRenderer = cube.GetComponent<Renderer>();

        // Get initial value of mode, 
        // Just this mechanism would be adequate if a one time check is acceptable. 
        MovingPlatformMode initialMovingPlatformMode = m_movingPlatformManager.Mode;

        // Find if It's possible to change the mode. 
        bool isSettable = m_movingPlatformManager.IsSetModeSupported();

        // Here you would add some use case specific logic using initialMovingPlatformMode and isSettable
        // to decide if you should ask the user if they want to change the mode. 

        // To set the mode.
        bool success = m_movingPlatformManager.TrySetMode(MovingPlatformMode.MovingPlatformOptimized);

        // Visual indicator of current state: Green = Moving Platform Optimized, Red = Regular.
        SetColourFromState(m_movingPlatformManager.Mode, cubeRenderer);

        // We set a callback to be notified if there's a change in mode. This is typically optional.
        m_movingPlatformManager.ModeChanged += CallbackOnMPMChanged;
        movingPlatformModeChanged = false;
    }

    // Update is called once per frame
    void Update()
    {
        // This must be done in the UI thread.
        if (movingPlatformModeChanged)
        {
            movingPlatformModeChanged = false;
            SetColourFromState(movingPlatformModeValue, cubeRenderer);
        }
    }

    // Sets renderer to:
    // Green = Moving Platform Mode Enabled
    // Red = Moving Platform Mode Disabled
    void SetColourFromState(MovingPlatformMode mode, Renderer thisRend)
    {
        if (mode == MovingPlatformMode.MovingPlatformOptimized)
        {
            thisRend.material.color = new Color(0f, 1f, 0f, 1f);
        }
        else
        {
            thisRend.material.color = new Color(1f, 0f, 0f, 1f);
        }
    }

    void CallbackOnMPMChanged(object sender, MovingPlatformEventArgs args)
    {
        movingPlatformModeChanged = true;
        movingPlatformModeValue = args.ModeEntered;
    }
}

另請參閱