2018 年 8 月

第 33 卷 8

本文章是由機器翻譯。

HoloLens-混合現實與 Fluent 設計

藉由Tim Kulp |2018 年 8 月

Microsoft 近來一直固定在混合的實境 (MR) 開發因為它在 2014 年引進 HoloLens,而且在 5 月的 Build 2018 會議,它提供絕佳的見解,Unity 開發環境中的新功能的豐富 MR、 以及 UI 設計最佳做法。在本文中,我將運用在組建,以說明如何使用 Microsoft 的 Fluent Design System 建置沉浸式體驗 MR 中的呈現的技術指導,具體來說,可讓透過 pictograms 通訊的非語言表達子系的 HoloLens 應用程式。

Microsoft 的 Fluent Design system 會採用三項核心原則,提供令人讚嘆的體驗。包括:

自適性:MR 必須橋接和 mingle 的真實世界和數位的元件,以建立全面性的體驗。因此,UI 必須留意的環境,同時增強 (但不是取代) 使用者的真實世界體驗。

直觀:MR 直觀設計著重於了解使用者的意圖,並需要在應用程式中體驗。做為範例,並非所有的使用者可以使用其實際操作的筆勢,因此 HoloLens clicker 和語音命令提供的輸入是直觀符合使用者需求的型態。

美觀:美觀的應用程式是 MR 中的主要挑戰。身為設計工具或開發人員,您必須擴充真實世界體驗,而不需要其負荷過重。需要仔細規劃和適當的工具。

Unity 是用於建立 MR 體驗的最常見的工具。Unity,根據其開發環境使用所建置的 HoloLens 和 MR 應用程式的 90%。雖然 Unity 有其自己的使用者介面系統,並不輕鬆轉譯 Fluent 設計。Microsoft 的小組具有內建混合實境工具組 (bit.ly/2yKyW2r) 及混合實境設計實驗室 (bit.ly/2MskePH) 工具,可協助開發人員建置透過絕佳 UXes元件的組態。使用這些專案,開發人員可以避免複雜的圖形設計工作,並專注於其應用程式的功能。在混合實境工具組和設計實驗室也已一起記載許多程式碼範例。在這篇文章中,我可以使用混合實境 Toolkit 2017.4.0.0 Unity 封裝來建立一個介面,並示範如何將各種元件一起拉到自己內聚、 唯一的介面。

設定您的 Unity 環境之前,請務必完成快速入門教學課程,從混合實境工具組 (bit.ly/2KcVvlN)。此專案中,我使用最新版 (撰寫本文時) 的 Unity 組建 2018.2.08b。使用 Unity 2018.2 需要混合實境工具組更新,但是升級不會造成任何衝突,如這篇文章中所實作的功能。

設計您的 UI MR

絕佳的 MR 體驗一開始有效的 UI 流程。不同於 Web 或行動裝置應用程式,MR 應用程式的 UI 會有一個大的未知: 環境。在 Web 開發您必須留意螢幕解析度和瀏覽器的功能,當您在行動裝置開發其的像素密度和電話功能。但 MR 的使用者實體周圍環境和環境變數的本質就十分重要。

將目標設為特定的環境中,我可以微調的實體空間和所使用裝置的特定功能。在 [我的範例應用程式,我要設計教室設定其中學生時,會使用其老師使用應用程式。這是良好的引發和相對較無訊息環境,也就是從倉儲或夜間 club 內部設計非常不同。規劃您的環境為基礎的 UI。

環境是外部使用者不僅也隨使用者的裝置功能。當考慮我的 UI,我需要留意可能的控制項,以使用。想要使用者的環境和功能,語音命令不會播放重要的角色,因為缺乏口頭溝通。筆勢會是有限的因為我的目標使用者可能也會有正常的馬達技能的挑戰。這會導致大型按鈕和工具,例如 HoloLens clicker 使用者選取按鈕。

我需要知道這一點之後,選取如何配置我 UI 美麗的設計。如果您是 Web 開發人員使用啟動程序 (或類似的 UI 架構),您已熟悉建置至方格。在 UWP 中,您必須如 StackPanel、 格線和畫布版面配置控制項。混合實境工具組中,您會有物件集合的元件。

物件集合元件可在混合實境 Toolkit 底下資產 |UX |指令碼 |物件集合。若要使用它,請場景中建立空的遊戲物件。空白的遊戲物件 「 MainContainer"命名,然後將物件集合的元件新增至空的遊戲物件。基於測試目的,將 cube 做為子物件加入 MainContainer。設定為 0.5 的 cube 的小數位數 x,0.2y,0.1z 讓它看起來像是精簡型的矩形。現在重複的 cube 做為子物件至 MainContainer 有九個 cube 總共八倍。

一旦加入 cube 時,按 [更新集合] 按鈕来套用至子物件的物件集合配置偵測器中。根據預設,物件的集合使用介面類型的純文字。我的 ui 中,我想要環繞感覺更擬真的使用者的集合。若要這樣做,更新偵測器中的球面物件集合介面型別。現在應該會出現如中所示的所有 cube [圖 1。物件的集合提供多個介面類型,以允許將使用者介面和吸引使用者特定案例。在本文稍後,我將示範如何使用不同的介面類型來達成不同的目標。

球體來更新介面的型別
[圖 1 更新至球體的介面的型別

我們要建置什麼?

非語言表達個子系有 pictograms,它們搭配老師表達其需求的書籍。每個圖示是單字或片語所孩子和教師同時建置。在本文中,我將示範如何建立 HoloLens,本書納入,讓學生建置其教師與通訊之句子的 MR 體驗。

我會先使用物件集合,將一大堆使用者選取要建置一個句子的按鈕。按鈕會 pictograms。啟動新增資源 |到您的專案視窗的 [資料] 資料夾。在 [data] 資料夾中建立 words.json 檔案來表示應用程式中的文字。範例程式碼會採用的短字檔案,為了簡單起見。

在 [專案] 視窗中,建立指令碼的資料夾,並在該資料夾內建立新 C# 指令碼呼叫 WordLoader。此元件讀取 words.json 檔案,並將它轉換成 C# Word 物件的集合。在設計實驗室中,有說明完成的範例,從檔案讀取資料和顯示 MR 體驗中的範例專案。定期資料表專案,以維持此範例的簡潔且熟悉的如中所示的程式碼將引述**[圖 2**。請查看期間資料表專案中,於bit.ly/2KmSizg其他功能和讀取資料檔案,並將結果繫結至物件集合為基礎的功能。

[圖 2 WordLoader 指令碼

[System.Serializable]
class Word
{
  public string category;
  public string text;
  public string image;
}
[System.Serializable]
class WordsData
{
  public Word[] words;
  public static WordsData FromJSON(string data)
  {
    return JsonUtility.FromJson<WordsData>(data);
  }
}

接下來,撰寫程式碼所示**[圖 3** WordLoader 元件。這個元件會從 JSON 檔案載入文字,並將它們為按鈕新增至物件集合。在元件中有兩個公用變數:父代是保留字物件集合和 WordPrefab 是用來代表 MR 體驗中的字數 prefab。

[圖 3 從 JSON 檔案載入文字

public class WordLoader : MonoBehaviour
{
  public ObjectCollection Parent;
  public GameObject WordPrefab;
  private void OnEnable() {
    if(Parent.transform.childCount > 0)
      return;
    TextAsset dataAsset = Resources.Load<TextAsset>("Data/words");
    WordsData wordData = WordsData.FromJSON(dataAsset.text);
    foreach (Word w in wordData.words) {
      GameObject newWord = Instantiate<GameObject>(WordPrefab, Parent.transform);
      newWord.GetComponent<CompoundButtonText>().Text = w.text;
      newWord.GetComponent<CompoundButtonIcon>().OverrideIcon = true;
      string iconPath = string.Format("Icons/{0}", w.image);
      newWord.GetComponent<CompoundButtonIcon>().iconOverride =
        (Texture2D)Resources.Load<Texture2D>(iconPath);
    }
    Parent.UpdateCollection();
  }
}

之後的所有文字會都載入至父代,則呼叫 Parent.UpdateCollection 將排列新建立的物件集合元件的版面配置為基礎的按鈕。變更屬性,以在物件集合的元件中,每次呼叫更新集合,以確保所有遊戲物件會正確更新。

現在在 Unity 編輯器中您會建立一個空遊戲物件 managers 應用程式,其中包含適用於場景的所有公用程式元件。新增 WordLoader 元件管理員,然後將父項設定 MainContainer。最後,設定要使用全像攝影版的按鈕 prefab WordPrefab (位於 [HoloToolkit |UX |Prefabs |按鈕)。這些按鈕實作 Fluent 設計概念,例如使用光以顯示焦點和動作。當使用者看到的按鈕都已啟動時,他知道選取的項目。

現在執行應用程式會在 word 資料檔案中建立的每個單字的按鈕 (請參閱**[圖 4**)。全像攝影版的按鈕會括住球體中的使用者。在播放模式中,放心地更新來試驗其他配置的物件集合的介面型別。調整儲存格間距,以及資料列計數來尋找適合的組合,針對您的體驗。若要查看在編輯器中的變更每個變更之後,請記得更新集合。

檢視為全像攝影版的按鈕,物件集合中的文字
[圖 4 檢視為全像攝影版的按鈕,物件集合中的文字

跟使用者

一旦建立物件集合的世界中會將它設定為特定的座標。當使用者移動,會保持物件集合,其中它最初建立。用於課堂這不會運作,因為子系不永遠保持在他的桌面。我需要更新要與使用者移動的真實世界各地的 UI。Fluent 設計中,您需要可彈性環境,即使當該人員移動,並變更恍神。

Build 2018 大會技術的工作階段 (「 建置以 HoloLens,倉儲大規模的應用程式bit.ly/2yNmwXt) 所述的挑戰與建置應用程式對於大於資料表上方的空間。這些保留 UI 元件時封鎖物件像堆高機來保留 UI 以使用者身分存取倉儲中所顯示的範圍移動一個位置,讓內部設計之類的專案。混合實境工具組將提供一些工具,可以使用規劃求解系統解決一些問題。

規劃求解系統可讓遊戲物件調整其大小或根據使用者的世界中移動的位置。在 Unity 中,您可以看到一些解使用編輯器,場景中的運作方式。若要新增規劃求解,請選取 MainContainer 物件並新增 SolverBodyLock 元件 (位於 [HoloToolkit |公用程式 |指令碼 |解)。SolverBodyLock 元件可以讓按鈕保持與使用者,球體,因為當使用者移動到空間 MainContainer 會隨之移動它們。若要測試這種情況,在編輯器中執行您的應用程式,並使用箭號或 WASD 鍵世界空間中移動。向前、 向後,您會發現,並存至移動保留與您 MainContainer。如果因為旋轉觀景窗,MainContainer 並未遵循您。

若要讓使用者依照他旋轉空間中的 UI,使用 SolverRadialView,其預設值會保留於使用者的週邊設備的檢視物件。有多少物件可見,可以增加或減少依據元件的設定。在此使用案例中,我不想搜尋的使用者,他,其實 SolverBodyLock 就已經足夠讓 UI。它會保留與使用者,但不是一定是在他們的臉部的按鈕的清單。

維護大小

在 [我的應用程式預期教室中移動的人員。在 MR,如同真實世界中,當人員離開物件,該物件會顯示較小。這會建立問題:使用較遠的物件上的目標 UI 元件的視線可能很困難,和圖示可能很難分辨很遠的地方。ConstantViewSize 求解器為了應付這個狀況的 UI 元件相應增加或相應減少根據使用者的距離。

此範例應用程式,您要新增的元件,可讓使用者建立的句子。每個按鈕已按下 MainContainer 將句子。例如,如果使用者想要說 「 我是飢餓的 」,他會按一下"I"] 按鈕,然後 「 是 」 按鈕,然後 「 飢餓 」 按鈕。每按一下會將句子容器中的文字。

在階層中建立新的空白遊戲物件,並呼叫句子。將物件集合的元件新增至句子、 平面和資料列的介面型別設為 1。這會建立為內容的資料列將不會破壞的一般介面。現在,將立方體加入句子遊戲物件,以便您可以看見作用中常數的大小規劃求解。稍後,我將從按鈕新增文字。設定 cube 的小數位數為 x = 1.4,y = 0.15 z = 0.1。如果您立即啟動應用程式,並移動整個空間,會縮小白色立方體,並隨著您移動離開更大且比較接近它最高。

若要鎖定 cuboid 的視覺大小,請新增 SolverConstantViewSize 元件到句子的物件。元件的小數位數可以也限制使用的最小和最大刻度範圍設定,讓您能夠控制大您想要擴大或縮小的 UI 元件以及在何種距離 — 這可讓您調整到教室 top,資料表中的元件到倉儲。

更多的解中有混合實境工具組,包括 Momentumizer 和介面磁場。建議您查看規劃求解系統並拓展 ui 的真實世界空間中的使用者可以使用您自己 MR 體驗 (bit.ly/2txcl4c)。

句子和收件者

若要啟用使用句子物件互相交流 MainContainer 按鈕,我實作的收件者會接收從 MainContainer 的已按下按鈕的事件,並將該按鈕的內容加入至這個句子。使用可互動的物件和混合實境工具組內建的接收者模式,連線 prefab 按鈕位於 HoloToolkit |UX |按鈕資料夾很簡單。

建立新 C# 指令碼呼叫您的專案的 Scripts 資料夾中的接收器中所示**[圖 5**。變更至 InteractionReceiver 繼承 MonoBehavior 指令碼。建立公用變數來保存到句子的遊戲物件的參考,並實作 InputDown 來回應使用者的覆寫方法,然後按一下 [全像攝影版的按鈕上的動作。

圖 5 接收器 C# 指令碼

public class Receiver : InteractionReceiver
{
  public ObjectCollection Sentence;
  protected override void InputDown(GameObject obj, InputEventData eventData)
  {
    switch (obj.name)
    {
      default:
        GameObject newObj = Instantiate(obj, Sentence.gameObject.transform);
        newObj.name = "Say" + obj.name;
        Sentence.UpdateCollection();
        break;
    }
  }

InputDown 方法中,內建立 switch 陳述式,以檢查 obj 遊戲物件的 name 屬性。現在,建立預設條件,不論遊戲物件名稱為何發生。預設陳述式內取得呼叫的物件,並建立它的句子遊戲物件底下的新執行個體。這會建立按鈕的新執行個體句子物件集合,而不需要向接收者。如果您按下按鈕句子物件中時,會發生任何事。在測試之前,請移除白色的 cuboid 預留位置,因此您可以查看出現在物件集合平面上的按鈕。

若要連接的接收者 MainContainer 中的按鈕,您會需要幾行程式碼新增至 WordLoader。應用程式載入的字,每個會註冊為 Interactable 接收者。Interactables 是使用接收器事件發生時回應 InteractableObject 元件的遊戲物件的清單。在 WordLoader onEnable 方法中,新增下列程式碼正下方 childCount 核取:

var receiver = GetComponent<Receiver>();
if (receiver == null)
  return;

此程式碼會檢查以確保收件者存在。然後在 foreach 迴圈中的字,請載入] 按鈕的圖示之後新增下列程式碼:

receiver.Registerinteractable(newWord);

Registerinteractable 將 interactables 份接收者遊戲的物件。現在按一下 MainContainer 中全像攝影版的按鈕觸發執行 InputDown 方法接收者,並建立一份已按下的按鈕。

有一些次要重新設定 MainContainer 物件集合的儲存格的大小和位置,您會看到類似下圖中所示**[圖 6**。

MainContainer 和更新後的句子物件集合
[圖 6 MainContainer 和更新後的句子物件集合

雖然我在此範例中使用的全像攝影版的按鈕,可互動的元件可以套用至任何項目從自訂的網狀結構的文字。可讓您的創意幫助您 imagine 令人讚嘆的介面。只要記住 MR 目的之一是合併數位和實體世界,使它們共同運作。

利用文字轉換語音

Fluent 設計的一部分要您的使用者需求直觀。在此範例中,您想要啟用這些缺乏口頭語音來傳情達意。現在,您需要使用大聲說使用者建立的項目在她的句子中的文字轉換語音。HoloToolkit 提供絕佳的元件,若要使用最少的程式碼或組態。如果您不使用 HoloLens,查看我的 MSDN Magazine 文章: 「 使用認知服務及混合實境"(msdn.com/magazine/mt814418),以了解如何使用 Azure 認知服務透過文字轉換語音。

若要開始使用文字轉換語音,加入您的專案階層架構中的音訊來源。這使用文字轉換語音元件來產生使用者若要聆聽的音訊。現在將 [文字轉換語音元件 (位於 [HoloToolkit |公用程式 |TextToSpeech) 到管理員遊戲物件。我使用管理員遊戲物件為主的所有公用程式方法 (接收者,則文字轉換語音) 來集中管理事件與這些事件會發生什麼事。在此情況下接收者會使用文字轉換語音元件到用於您有相同的收件者安裝程式將文字新增到句子的句子。將文字轉換語音元件設定為使用您剛才建立的偵測器中選取音訊來源。

在接收者,我偵測任何文字存在於這個句子,而所以,我將在其中加入一個按鈕,會顯示這個句子。新增稱為 SayButton 到接收者元件的新遊戲物件公用變數。

public GameObject SayButton;

這會做為 [Say 按鈕 prefab。Switch 陳述式的預設區塊內加入下列的 if 陳述式之前將新物件加入至這個句子:

if (Sentence.transform.childCount == 0)
{
  GameObject newSayButton = Instantiate(SayButton, Sentence.transform);
  newSayButton.name = "Say";
  newSayButton.GetComponent<CompoundButtonText>().Text = "Say: ";
  GetComponent<Receiver>().Registerinteractable(newSayButton);
}

在此情況下時句子物件中沒有任何子系,例如將按鈕加入任何其他按鈕之前。這會避開說出的最左邊的任何句子的句子物件。接下來,建立新的 case 陳述式中切換至偵測 Say 按鈕的名稱。請記住,交換器為基礎 obj.name,當您建立此按鈕時您將名稱設定為 「 假設 」。 請看看下面這個程式碼:

case "Say":
  StringBuilder sentenceText = new StringBuilder();
  foreach (CompoundButtonText text in
    Sentence.GetComponentsInChildren<CompoundButtonText>())
  {
    sentenceText.Append(text.Text + " ");
  }
  TextToSpeech tts = GetComponent<TextToSpeech>();
  tts.StartSpeaking(sentenceText.ToString());
  break;

此情況下會顯示按鈕偵測依名稱,並再執行迴圈句子,以建置 TextToSpeech 元件的文字字串的所有子系假設為句子。當使用者完成建置陳述式,他可以按 [Say] 按鈕,以表達他的陳述式。為了簡單起見我沒有您實作 HoloToolkit 文字轉換語音管理員 (bit.ly/2lxJpoq),但最好能避免的情況下,例如使用者按 Say 一再重複,則文字轉換語音嘗試同時顯示多項作業的元件。

總結

使用 Fluent 設計與 MR 很自然地。混合實境工具組和混合實境設計實驗室等的工具是絕佳 springboards 來建置、 直觀和美觀的體驗。在本文中我討論了如何實作一些將會顯示在 [Build 2018 MR 的體驗。使用物件集合做為版面配置工具,規劃求解系統,以保留與使用者的 UI,通過空間,並再連線體驗與集中式的事件管理的接收者,我說明了如何快速建置 MR 應用程式。

使用混合實境 Toolkit 中的範例,您可以將此範例應用程式進一步使用新的介面選項和功能。檢閱如何建置卓越的體驗,blend 實體與數位世界取得進一步的靈感的 Build 2018 MR 工作階段。


Tim Kulp主管的新興技術考量移轉中的機器 Baltimore,md他是混合的實境、 人工智慧與雲端應用程式開發人員,以及作者、 複製、 父親和"wannabe 瘋狂的科學家建立者 」。 在 Twitter 上找到他: @tim_kulp或透過 LinkedIn: linkedin.com/in/timkulp

非常感謝下列技術專家檢閱這篇文章:將真 (Balti 虛擬)


MSDN Magazine 論壇中的這篇文章的討論