HoloLens (第 1 代) 和 Azure 308:跨裝置通知
注意
混合實境學院教學課程的設計是以 HoloLens (第 1 代) 和混合實境沉浸式頭戴裝置為準。 因此,對於仍在尋找這些裝置開發指引的開發人員而言,我們覺得這些教學課程很重要。 這些教學課程不會使用用於 HoloLens 2 的最新工具組或互動進行更新。 系統會保留這些資訊,以繼續在支援的裝置上運作。 未來將會張貼一系列新的教學課程,示範如何針對HoloLens 2進行開發。 此通知會在張貼時更新這些教學課程的連結。
在此課程中,您將瞭解如何使用 Azure 通知中樞、Azure 資料表和Azure Functions,將通知中樞功能新增至混合實境應用程式。
Azure 通知中樞 是一項 Microsoft 服務,可讓開發人員將目標和個人化的推播通知傳送至雲端內所有平臺。 這可以有效地讓開發人員與終端使用者通訊,或甚至根據案例在各種應用程式之間進行通訊。 如需詳細資訊,請流覽 Azure 通知中樞頁面。
Azure Functions是 Microsoft 服務,可讓開發人員在 Azure 中執行小型程式碼片段'functions'。 這提供將工作委派給雲端的方式,而不是您的本機應用程式,這有許多優點。 Azure Functions支援數種開發語言,包括 C#、F#、Node.js、JAVA 和 PHP。 如需詳細資訊,請流覽Azure Functionspage。
Azure 資料表 是 Microsoft 雲端服務,可讓開發人員將結構化非 SQL 資料儲存在雲端中,使其可在任何地方輕鬆存取。 此服務會支援無架構設計,可視需要演進資料表,因此非常有彈性。 如需詳細資訊,請流覽 Azure 資料表頁面
完成本課程之後,您將擁有混合實境沉浸式頭戴式裝置應用程式,以及桌上型電腦應用程式,這可以執行下列動作:
桌上型電腦應用程式可讓使用者使用滑鼠,在 2D 空間中移動物件 (X 和 Y) 。
電腦應用程式內的物件移動將會使用 JSON 傳送至雲端,其格式為字串,其中包含物件識別碼、類型和轉換資訊, (X 和 Y 座標) 。
混合實境應用程式與傳統型應用程式具有相同場景,將會從通知中樞服務收到有關物件移動的通知, (電腦應用程式剛更新) 。
收到包含物件識別碼、類型和轉換資訊的通知時,混合實境應用程式會將接收的資訊套用至自己的場景。
在您的應用程式中,您必須先瞭解如何將結果與您的設計整合。 本課程旨在教導您如何整合 Azure 服務與您的 Unity 專案。 您的工作是使用此課程取得的知識來增強混合實境應用程式。 本課程是獨立的教學課程,不會直接涉及任何其他Mixed Reality Labs。
裝置支援
課程 | HoloLens | 沉浸式頭戴裝置 |
---|---|---|
MR 和 Azure 308:跨裝置通知 | ✔️ | ✔️ |
注意
雖然本課程主要著重于Windows Mixed Reality沉浸式 (VR) 頭戴式裝置,但您也可以將此課程中學到的內容套用至Microsoft HoloLens。 當您遵循本課程時,您會看到可能需要採用以支援 HoloLens 的任何變更注意事項。 使用 HoloLens 時,您可能會在語音擷取期間注意到一些回應。
必要條件
注意
本教學課程專為具備 Unity 和 C# 基本體驗的開發人員所設計。 另請注意,本檔中的必要條件和書面指示代表在撰寫 (2018 年 5 月) 時已測試及驗證的內容。 您可以隨意使用最新的軟體,如 安裝工具 一文中所列,但不應該假設本課程中的資訊會完全符合您在較新軟體中找到的內容,而不是下面所列的內容。
針對本課程,我們建議使用下列硬體和軟體:
- 開發電腦,與Windows Mixed Reality相容以進行沉浸式 (VR) 頭戴式裝置開發
- 已啟用開發人員模式的Windows 10 Fall Creators Update (或更新版本)
- 最新的Windows 10 SDK
- Unity 2017.4
- Visual Studio 2017
- 已啟用開發人員模式的Windows Mixed Reality沉浸式 (VR) 頭戴式裝置或Microsoft HoloLens
- Azure 設定和存取通知中樞的網際網路存取
在您開始使用 Intune 之前
- 若要避免建置此專案時發生問題,強烈建議您在根資料夾或近根資料夾中建立本教學課程中提及的專案, (長資料夾路徑可能會導致建置時間) 的問題。
- 您必須是 Microsoft 開發人員入口網站和應用程式註冊入口網站的擁有者,否則您將沒有在 第 2 章中存取應用程式的許可權。
第 1 章 - 在 Microsoft 開發人員入口網站上建立應用程式
若要使用 Azure 通知 中樞服務,您必須在 Microsoft 開發人員入口網站上建立應用程式,因為您的應用程式必須註冊,以便傳送和接收通知。
-
您必須登入您的 Microsoft 帳戶。
從 [儀表板] 中,按一下 [建立新的應用程式]。
隨即會出現快顯視窗,其中您需要保留新應用程式的名稱。 在文字方塊中,插入適當的名稱;如果所選的名稱可用,則文字方塊右側會出現刻度。 插入可用的名稱之後,請按一下快顯左下方的 [保留產品名稱 ] 按鈕。
現在建立應用程式之後,您就可以移至下一章。
第 2 章 - 擷取新的應用程式認證
登入應用程式註冊入口網站,其中會列出您的新應用程式,並擷取認證,以用來在Azure入口網站中設定通知中樞服務。
流覽至 應用程式註冊入口網站。
警告
您必須使用您的 Microsoft 帳戶登入。
這 必須是 您在上 一章中使用的 Microsoft 帳戶,以及 Windows 市集開發人員入口網站。您會在 [ 我的應用程式 ] 區段下找到您的應用程式。 找到它之後,按一下它,您就會進入新的頁面,其中包含應用程式名稱加上 [註冊]。
向下捲動註冊頁面,以尋找您的應用程式 的應用程式秘密 區段和 套件 SID 。 複製這兩者以搭配下一章設定 Azure 通知中樞服務 使用。
第 3 章 - 設定 Azure 入口網站:建立通知中樞服務
擷取您的應用程式認證後,您必須移至 Azure 入口網站,您將在其中建立 Azure 通知中樞服務。
登入 Azure 入口網站。
注意
如果您還沒有 Azure 帳戶,則必須建立一個帳戶。 如果您在教室或實驗室案例中遵循本教學課程,請詢問講師或其中一個專業人員,以協助設定新的帳戶。
登入之後,按一下左上角的 [ 新增 ],然後搜尋 [通知中樞],然後按一下 [輸入]。
注意
New一詞可能已取代為在較新的入口網站中建立資源。
新頁面將提供 通知中樞 服務的描述。 在此提示的左下方,選取 [ 建立 ] 按鈕,以建立與此服務的關聯。
按一下 [ 建立] 之後:
插入此服務實例所需的名稱。
提供 命名空間 ,您將能夠與此應用程式產生關聯。
選取 [位置]。
選擇 資源群組 或建立新的群組。 資源群組提供一種方式來監視、控制存取、布建和管理 Azure 資產集合的計費。 建議您保留與單一專案相關聯的所有 Azure 服務 (例如,這些實驗室) 在通用資源群組底下) 。
如果您想要深入瞭解 Azure 資源群組,請遵循此 連結以瞭解如何管理資源群組。
選取適當的 訂用帳戶。
您也必須確認您已瞭解套用至此服務的條款及條件。
選取 [建立] 。
按一下 [ 建立] 之後,您必須等候服務建立,這可能需要一分鐘的時間。
建立服務實例之後,入口網站中會出現通知。
按一下通知中的 [ 移至資源] 按鈕,以探索新的服務實例。 系統會帶您前往新的 通知中樞 服務實例。
在概觀頁面中,按一下頁面的一半,按一下 [Windows (WNS) ]。 右側的面板會變更以顯示兩個文字欄位,這需要您先前設定的應用程式中的 套件 SID 和安全性 金鑰。
將詳細資料複製到正確的欄位之後,請按一下 [ 儲存],並在通知中樞成功更新時收到通知。
第 4 章 - 設定 Azure 入口網站:建立資料表服務
建立通知中樞服務實例之後,請流覽回您的 Azure 入口網站,您可以在其中建立儲存體資源來建立 Azure 資料表服務。
如果尚未登入,請登入 Azure 入口網站。
登入之後,按一下左上角的 [ 新增 ],然後搜尋 儲存體帳戶,然後按一下 Enter。
注意
New一詞可能已取代為在較新的入口網站中建立資源。
從清單中選取 [儲存體帳戶 - Blob、檔案、資料表、佇列 ]。
新的頁面將提供 儲存體帳戶 服務的描述。 在此提示的左下角,選取 [ 建立 ] 按鈕,以建立此服務的實例。
按一下 [ 建立] 之後,會出現面板:
插入此服務實例所需的 Name (必須是小寫) 。
針對 [部署模型],按一下 [資源管理員]。
針對 [帳戶種類],使用下拉式功能表,選取 [ 儲存體] (一般用途 v1) 。
選取適當的 位置。
針對 [ 複寫] 下拉式功能表,選取 [ 讀取權限-異地備援儲存體] (RA-GRS) 。
針對 [效能],按一下 [ 標準]。
在 [需要安全傳輸] 區段中,選取 [已停用]。
從 [ 訂用帳戶 ] 下拉式功能表中,選取適當的訂用帳戶。
選擇 資源群組 或建立新的群組。 資源群組提供一種方式來監視、控制存取、布建和管理 Azure 資產集合的計費。 建議您保留與單一專案相關聯的所有 Azure 服務 (例如,這些實驗室) 在通用資源群組底下) 。
如果您想要深入瞭解 Azure 資源群組,請遵循此 連結以瞭解如何管理資源群組。
如果這是選項,請將 [虛擬網路 ] 保留為 [已停用 ]。
按一下 [建立]。
按一下 [ 建立] 之後,您必須等候服務建立,這可能需要一分鐘的時間。
建立服務實例之後,入口網站中會出現通知。 按一下通知以探索新的服務實例。
按一下通知中的 [ 移至資源] 按鈕,以探索新的服務實例。 系統會帶您前往新的儲存體服務實例概觀頁面。
從概觀頁面,按一下右側的 [ 資料表]。
右側的面板會變更以顯示 資料表服務 資訊,其中您需要新增資料表。 按一下左上角的 [ +資料表] 按鈕即可執行此動作。
將會顯示新的頁面,其中您需要輸入 資料表名稱。 這是您將在稍後的 Chapters 中參考應用程式中資料的名稱。 插入適當的名稱,然後按一下 [ 確定]。
建立新的資料表之後,您就可以在底部的 [ 資料表服務 ] 頁面 (看到它) 。
第 5 章 - 在 Visual Studio 中完成 Azure 資料表
現在已設定您的 資料表服務 儲存體帳戶,現在可以將資料加入其中,以便用來儲存和擷取資訊。 您可以透過 Visual Studio編輯資料表。
開啟 Visual Studio。
從功能表中,按一下 [檢視>雲端總管]。
Cloud Explorer會以停駐專案的形式開啟, (病患,因為載入可能需要時間) 。
注意
如果您用來建立 儲存體帳戶 的訂用帳戶看不到,請確定您有:
登入與您用於 Azure 入口網站之帳戶相同的帳戶。
從帳戶管理頁面選取您的訂用帳戶 (您可能需要從您的帳戶設定套用篩選) :
將會顯示您的 Azure 雲端服務。 尋找 [儲存體帳戶 ],然後按一下該帳戶左邊的箭號,以展開您的帳戶。
展開之後,應該可以使用您新建立的 儲存體帳戶 。 按一下儲存體左側的箭號,然後在展開之後,尋找 [ 資料表 ],然後按一下該位置旁的箭號,以顯示您在上一章中建立的 資料表 。 按兩下您的 資料表。
您的資料表將會在 Visual Studio 視窗的中心開啟。 按一下具有 (加上) 的資料表圖示 + 。
隨即會出現一個視窗,提示您 新增實體。 您將總共建立三個實體,每個實體都有數個屬性。 您會發現已提供 PartitionKey 和 RowKey ,因為資料表會使用這些資料來尋找您的資料。
更新PartitionKey和RowKey的值,如下所示 (請記得針對您新增的每個資料列屬性執行這項操作,但每次) 遞增 RowKey:
按一下 [新增屬性 ] 以新增額外的資料列。 讓您的第一個空白資料表符合下表。
完成時按一下 [ 確定 ]。
警告
確定 您已將X、 Y和 Z的類型變更為 Double。
您會注意到資料表現在有一個資料列。 +再次按一下 (加) 圖示以新增另一個實體。
建立其他屬性,然後設定新實體的值,以符合如下所示的值。
重複最後一個步驟以新增另一個實體。 將此實體的值設定為如下所示的值。
您的資料表現在看起來應該像下面這樣。
您已完成本章。 請務必儲存。
第 6 章 - 建立 Azure 函式應用程式
建立 Azure 函式應用程式,由傳統型應用程式呼叫以更新 資料表 服務,並透過 通知中樞傳送通知。
首先,您需要建立一個檔案,讓您的 Azure 函式能夠載入所需的程式庫。
開啟 [記事本 ] (按 Windows 鍵,然後輸入記事本) 。
在 [記事本] 開啟時,將下面的 JSON 結構插入其中。 完成後,請將它儲存在您的桌面上作為 project.json。 命名正確很重要:請確定其 沒有.txt 副檔名。 如果您已使用 NuGet,此檔案會定義函式將使用的程式庫,看起來會很熟悉。
{ "frameworks": { "net46":{ "dependencies": { "WindowsAzure.Storage": "7.0.0", "Microsoft.Azure.NotificationHubs" : "1.0.9", "Microsoft.Azure.WebJobs.Extensions.NotificationHubs" :"1.1.0" } } } }
登入 Azure 入口網站。
登入之後,按一下左上角的 [ 新增 ],然後搜尋 函數應用程式,然後按 Enter。
注意
在較新的入口網站中, [新增 ] 這個字可能已取代為 建立資源。
新頁面將提供 函式 App Service 的描述。 在此提示的左下角,選取 [ 建立 ] 按鈕,以建立與此服務的關聯。
按一下 [ 建立] 之後,請填寫下列內容:
針對 [應用程式名稱],插入此服務實例所需的名稱。
選取 [訂用帳戶] 。
選取適合您的定價層,如果這是第一次建立函式App Service,則免費層應該可供您使用。
選擇 資源群組 或建立新的群組。 資源群組提供一種方式來監視、控制存取、布建和管理 Azure 資產集合的計費。 建議將所有與單一專案相關聯的 Azure 服務保留 (例如,這些實驗室) 在通用資源群組) 下。
如果您想要深入瞭解 Azure 資源群組,請遵循此 連結以瞭解如何管理資源群組。
針對 [作業系統],按一下 [Windows],如同預期平臺一樣。
(本教學 課程 使用取用方案,請選取主 控方案。
選取 [位置 ] (選擇與您在上一個步驟中建置的儲存體相同的位置)
針對 [ 儲存體 ] 區段, 您必須選取您在上一個步驟中建立的儲存體服務。
您不需要此應用程式中的 Application Insights ,因此請放心地將其 關閉。
按一下 [建立]。
按一下 [ 建立 ] 之後,您必須等候服務建立,這可能需要一分鐘的時間。
建立服務實例之後,入口網站中會出現通知。
按一下通知以探索新的服務實例。
按一下通知中的 [ 移至資源 ] 按鈕,以探索新的服務實例。
按一下函 + 式旁的 (加上) 圖示,以建立新的。
在中央面板中,[ 函 式建立] 視窗隨即出現。 忽略面板上半部的資訊,然後按一下 [ 自訂] 函式,其位於藍色區域中底部 (附近,如下所示) 。
視窗中的新頁面會顯示各種函式類型。 向下捲動以檢視紫色類型,然後按一下 [HTTP PUT ] 元素。
重要
如果您已) Azure 入口網站更新,您可能必須向下捲動頁面 (,而且此映射看起來可能不完全相同,不過,您要尋找稱為 HTTP PUT的專案。
HTTP PUT 視窗隨即出現,您需要在其中設定函式 (請參閱下方的影像) 。
針對 [語言], 使用下拉式功能表選取 [C#]。
針對 [名稱], 輸入適當的名稱。
在 [ 驗證層級 ] 下拉式功能表中,選取 [ 函式]。
針對 [ 資料表名稱 ] 區段,您必須使用您先前用來建立 資料表 服務的確切名稱, (包括相同的字母大小寫) 。
在 [ 儲存體帳戶連線 ] 區段中,使用下拉式功能表,然後從該處選取您的儲存體帳戶。 如果不存在,請按一下區段標題旁的 [ 新增 ] 超連結,以顯示另一個面板,其中應該列出您的儲存體帳戶。
按一下 [建立 ],您會收到已成功更新設定的通知。
按一下 [建立]之後,系統會將您重新導向至函式編輯器。
將下列程式碼插入函式編輯器中, (取代函式中的程式碼) :
#r "Microsoft.WindowsAzure.Storage" using System; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Table; using Microsoft.Azure.NotificationHubs; using Newtonsoft.Json; public static async Task Run(UnityGameObject gameObj, CloudTable table, IAsyncCollector<Notification> notification, TraceWriter log) { //RowKey of the table object to be changed string rowKey = gameObj.RowKey; //Retrieve the table object by its RowKey TableOperation operation = TableOperation.Retrieve<UnityGameObject>("UnityPartitionKey", rowKey); TableResult result = table.Execute(operation); //Create a UnityGameObject so to set its parameters UnityGameObject existingGameObj = (UnityGameObject)result.Result; existingGameObj.RowKey = rowKey; existingGameObj.X = gameObj.X; existingGameObj.Y = gameObj.Y; existingGameObj.Z = gameObj.Z; //Replace the table appropriate table Entity with the value of the UnityGameObject operation = TableOperation.Replace(existingGameObj); table.Execute(operation); log.Verbose($"Updated object position"); //Serialize the UnityGameObject string wnsNotificationPayload = JsonConvert.SerializeObject(existingGameObj); log.Info($"{wnsNotificationPayload}"); var headers = new Dictionary<string, string>(); headers["X-WNS-Type"] = @"wns/raw"; //Send the raw notification to subscribed devices await notification.AddAsync(new WindowsNotification(wnsNotificationPayload, headers)); log.Verbose($"Sent notification"); } // This UnityGameObject represent a Table Entity public class UnityGameObject : TableEntity { public string Type { get; set; } public double X { get; set; } public double Y { get; set; } public double Z { get; set; } public string RowKey { get; set; } }
注意
函式會使用包含的程式庫,接收物件的名稱和位置,該物件在 Unity 場景中移動 (為 C# 物件,稱為 UnityGameObject) 。 然後,此物件會用來更新所建立資料表內的物件參數。 接著,函式會呼叫您建立的通知中樞服務,以通知所有已訂閱的應用程式。
就地執行程式碼後,按一下 [ 儲存]。
接下來,按一下 < 頁面右側 (箭號) 圖示。
面板會從右側滑入。 在該面板中,按一下 [ 上傳],[檔案瀏覽器] 隨即出現。
流覽至 ,然後按一下您先前在[記事本] 中建立的project.json檔案,然後按一下 [開啟] 按鈕。 此檔案會定義函式將使用的程式庫。
檔案上傳後,它會出現在右側的面板中。 按一下它會在 函式 編輯器中開啟它。 其看起來必須與下一個影像 完全相同 , (步驟 23) 下方。
然後,在左側面板的 [函式] 下方,按一下 [ 整合 ] 連結。
在下一頁的右上角,按一下 [ 進階編輯器 ] (,如下所示) 。
函式.json檔案將會在中央面板中開啟,此檔案必須取代為下列程式碼片段。 這會定義您要建置的函式,以及傳入函式的參數。
{ "bindings": [ { "authLevel": "function", "type": "httpTrigger", "methods": [ "get", "post" ], "name": "gameObj", "direction": "in" }, { "type": "table", "name": "table", "tableName": "SceneObjectsTable", "connection": "mrnothubstorage_STORAGE", "direction": "in" }, { "type": "notificationHub", "direction": "out", "name": "notification", "hubName": "MR_NotHub_ServiceInstance", "connection": "MRNotHubNS_DefaultFullSharedAccessSignature_NH", "platform": "wns" } ] }
您的編輯器現在看起來應該像下圖:
您可能會注意到您剛才插入的輸入參數可能不符合您的資料表和儲存體詳細資料,因此必須以您的資訊進行更新。 請勿在此執行此動作,因為接下來會加以說明。 只要按一下頁面右上角的標準 編輯器 連結,即可返回。
回到標準編輯器,按一下 [輸入] 底下的 [Azure 資料表儲存體 (資料表) ]。
請確定下列 專案與您的資訊 相符,因為它們可能不同 (下圖) :
資料表名稱:您在 Azure 儲存體、資料表服務內建立的資料表名稱。
儲存體帳戶連線: 按一下 [新增],其會出現在下拉式功能表旁,而面板會出現在視窗右側。
選取您先前建立的 儲存體帳戶來裝載 函式應用程式。
您會注意到已建立 儲存體帳戶 連線值。
完成之後,請務必按 [儲存 ]。
[ 輸入] 頁面現在應該符合下列內容,其中顯示 您的資訊 。
接下來,按一下 [輸出] 底下的[Azure 通知中樞] (通知) 。 請確定下列 專案與您的資訊 相符,因為它們可能不同, (下列步驟下方有影像) :
通知中樞名稱:這是您先前建立的 通知中樞 服務實例名稱。
通知中樞命名空間連線:按一下 [新增],其會出現在下拉式功能表旁。
[連線] 快顯視窗會顯示 (下圖) ,您需要選取您先前設定的通知中樞命名空間。
從中間下拉式功能表中選取您的 通知中樞 名稱。
將 [ 原則 ] 下拉式功能表設定為 DefaultFullSharedAccessSignature。
按一下 [ 選取] 按鈕以返回。
[ 輸出] 頁面現在應該符合下列內容,但會改為 與您的 資訊相符。 請務必按 [儲存]。
警告
請勿直接編輯通知中樞名稱, (這應該全部都使用進階編輯器來完成,前提是您已正確遵循先前的步驟。
此時,您應該測試函式,以確保函式正常運作。 若要這樣做:
再次流覽至函式頁面:
回到函式頁面,按一下頁面最右側的 [ 測試 ] 索引標籤,以開啟 [ 測試 ] 刀鋒視窗:
在刀鋒視窗的 [ 要求本文] 文字方塊中,貼上下列程式碼:
{ "Type":null, "X":3, "Y":0, "Z":1, "PartitionKey":null, "RowKey":"Obj2", "Timestamp":"0001-01-01T00:00:00+00:00", "ETag":null }
在測試程式碼就緒後,按一下右下角的 [ 執行 ] 按鈕,並執行測試。 測試的輸出記錄會出現在主控台區域中,您的函式程式碼下方。
警告
如果上述測試失敗,您必須仔細檢查您是否確實遵循上述步驟,特別是 整合面板中的設定。
第 7 章 - 設定桌面 Unity 專案
重要
您目前正在建立的桌面應用程式 無法在 Unity 編輯器中運作。 它必須在編輯器外部執行,遵循建置應用程式,使用 Visual Studio (或已部署的應用程式) 。
以下是使用 Unity 和混合實境進行開發的一般設定,因此是其他專案的良好範本。
設定及測試混合實境沉浸式頭戴式裝置。
注意
您 不需要 此課程的動作控制器。 如果您需要設定沉浸式頭戴式裝置的支援,請遵循此連結來瞭解如何設定Windows Mixed Reality。
開啟 Unity ,然後按一下 [ 新增]。
您需要提供 Unity 專案名稱,插入 UnityDesktopNotifHub。 請確定專案類型已設定為 3D。 將 [位置 ] 設定為適合您 (記住,較接近根目錄的較佳) 。 然後按一下 [ 建立專案]。
開啟 Unity 時,值得檢查預設 腳本編輯器 已設定為 Visual Studio。 移至[編輯>喜好設定],然後從新視窗流覽至[外部工具]。 將 外部腳本編輯器 變更為 Visual Studio 2017。 關閉 [喜好設定] 視窗。
接下來,移至 [檔案>建置設定] 並選取[通用 Windows 平臺],然後按一下 [切換平臺] 按鈕以套用您的選取專案。
在 [檔案>建置設定] 中,請確定:
目標裝置 已設定為 [任何裝置]
此應用程式將適用于您的桌面,因此必須是 任何裝置
組建類型 設定為 D3D
SDK 已設定為 [最新安裝]
Visual Studio 版本 設定為 [最新安裝]
[建置並執行 ] 設定為 [ 本機電腦]
在這裡,值得儲存場景,並將它新增至組建。
選取 [ 新增開啟場景]來執行此動作。 隨即會出現儲存視窗。
為此建立新的資料夾,以及任何未來的場景,然後選取 [ 新增資料夾 ] 按鈕,以建立新的資料夾,並將其命名為 Scenes。
開啟新建立的 Scenes 資料夾,然後在 [ 檔案名: 文字] 欄位中,輸入 NH_Desktop_Scene,然後按 [ 儲存]。
建置 設定中的其餘設定現在應該保留為預設值。
在相同的視窗中,按一下 [ 播放程式設定 ] 按鈕,這會在 Inspector 所在的空間中開啟相關的面板。
在此面板中,必須驗證一些設定:
在 [ 其他設定] 索引 標籤中:
腳本執行時間版本 應該是 實驗性 (.NET 4.6 對等)
腳本後端 應該是 .NET
API 相容性層級 應該是 .NET 4.6
在 [ 發佈設定] 索引標籤的 [ 功能] 底下,檢查:
InternetClient
回到 組建設定Unity C# 專案 不再呈現灰色;勾選此旁的核取方塊。
關閉 [組建設定] 視窗。
儲存場景和專案檔>儲存場景/檔案>儲存專案。
重要
如果您想要略過此專案的 Unity 設定 元件, (傳統型應用程式) ,然後直接進入程式碼,請隨意 下載此 .unitypackage、將它匯入您的專案作為 自訂套件,然後從 第 9 章繼續進行。 您仍然需要新增腳本元件。
第 8 章 - 在 Unity 中匯入 DLL
您將使用適用于 Unity 的 Azure 儲存體 (,其本身會利用適用于 Azure 的 .Net SDK) 。 如需詳細資訊,請遵循此 連結以瞭解適用于 Unity 的 Azure 儲存體。
Unity 中目前有已知問題,需要在匯入之後重新設定外掛程式。 本節中的這些步驟 (4 - 7,) 在 Bug 解決之後就不再需要這些步驟。
若要將 SDK 匯入您自己的專案,請確定您已從 GitHub 下載最新的 .unitypackage 。 然後執行下列動作:
使用 [資產 > 匯入套件自訂套件 >] 功能表選項,將.unitypackage新增至 Unity。
在快顯的 [匯入 Unity 套件] 方塊中,您可以選取[外掛程式>儲存體] 底下的所有專案。 取消核取所有其他專案,因為此課程不需要。
按一下 [ 匯入 ] 按鈕,將專案新增至您的專案。
移至 [專案] 檢視中[外掛程式] 底下的 [儲存體] 資料夾,並只選取下列外掛程式:
- Microsoft.Data.Edm
- Microsoft.Data.OData
- Microsoft.WindowsAzure.Storage
- Newtonsoft.Json
- System.Spatial
選取 這些特定外掛程式後 , 取消核取[任何平臺 ],然後 取消核取[WSAPlayer ],然後按一下 [ 套用]。
注意
我們會將這些特定外掛程式標示為只在 Unity 編輯器中使用。 這是因為 WSA 資料夾中有不同版本的相同外掛程式,將在專案從 Unity 匯出之後使用。
在 [ 儲存體 外掛程式] 資料夾中,只選取:
Microsoft.Data.Services.Client
核取 [平臺設定] 底下的[不要處理] 方塊,然後按一下 [套用]。
注意
我們正在標示此外掛程式「不要處理」,因為 Unity 元件修補程式處理此外掛程式時發生困難。 即使未處理外掛程式,外掛程式仍可運作。
第 9 章 - 在 Desktop Unity 專案中建立 TableToScene 類別
您現在必須建立包含執行此應用程式之程式碼的腳本。
您需要建立的第一個腳本是 TableToScene,負責:
- 讀取 Azure 資料表內的實體。
- 使用資料表資料,判斷要繁衍的物件,以及哪個位置。
您需要建立的第二個腳本是 CloudScene,負責:
- 註冊滑鼠左鍵事件,讓使用者在場景周圍拖曳物件。
- 從這個 Unity 場景序列化物件資料,並將其傳送至 Azure 函式應用程式。
若要建立此類別:
以滑鼠右鍵按一下 [資產資料夾] 位於 [專案面板] 的 [建立>資料夾]。 將資料夾命名為 Scripts。
按兩下剛才建立的資料夾,以開啟它。
在[腳本]資料夾內按一下滑鼠右鍵,按一下 [建立>C# 腳本]。 將腳本命名為 TableToScene。
按兩下腳本,在 Visual Studio 2017 中加以開啟。
新增下列命名空間:
using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Auth; using Microsoft.WindowsAzure.Storage.Table; using UnityEngine;
在 類別中,插入下列變數:
/// <summary> /// allows this class to behave like a singleton /// </summary> public static TableToScene instance; /// <summary> /// Insert here you Azure Storage name /// </summary> private string accountName = " -- Insert your Azure Storage name -- "; /// <summary> /// Insert here you Azure Storage key /// </summary> private string accountKey = " -- Insert your Azure Storage key -- ";
注意
將 accountName 值取代為您的 Azure 儲存體服務名稱和 accountKey 值,取代為 Azure 儲存體服務中找到的金鑰值,在 Azure 入口網站中 (請參閱下圖) 。
現在新增 Start () 和 Awake () 方法來初始化 類別。
/// <summary> /// Triggers before initialization /// </summary> void Awake() { // static instance of this class instance = this; } /// <summary> /// Use this for initialization /// </summary> void Start() { // Call method to populate the scene with new objects as // pecified in the Azure Table PopulateSceneFromTableAsync(); }
在 TableToScene 類別中,新增方法,以從 Azure 資料表擷取值,並使用它們來繁衍場景中的適當基本類型。
/// <summary> /// Populate the scene with new objects as specified in the Azure Table /// </summary> private async void PopulateSceneFromTableAsync() { // Obtain credentials for the Azure Storage StorageCredentials creds = new StorageCredentials(accountName, accountKey); // Storage account CloudStorageAccount account = new CloudStorageAccount(creds, useHttps: true); // Storage client CloudTableClient client = account.CreateCloudTableClient(); // Table reference CloudTable table = client.GetTableReference("SceneObjectsTable"); TableContinuationToken token = null; // Query the table for every existing Entity do { // Queries the whole table by breaking it into segments // (would happen only if the table had huge number of Entities) TableQuerySegment<AzureTableEntity> queryResult = await table.ExecuteQuerySegmentedAsync(new TableQuery<AzureTableEntity>(), token); foreach (AzureTableEntity entity in queryResult.Results) { GameObject newSceneGameObject = null; Color newColor; // check for the Entity Type and spawn in the scene the appropriate Primitive switch (entity.Type) { case "Cube": // Create a Cube in the scene newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Cube); newColor = Color.blue; break; case "Sphere": // Create a Sphere in the scene newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Sphere); newColor = Color.red; break; case "Cylinder": // Create a Cylinder in the scene newSceneGameObject = GameObject.CreatePrimitive(PrimitiveType.Cylinder); newColor = Color.yellow; break; default: newColor = Color.white; break; } newSceneGameObject.name = entity.RowKey; newSceneGameObject.GetComponent<MeshRenderer>().material = new Material(Shader.Find("Diffuse")) { color = newColor }; //check for the Entity X,Y,Z and move the Primitive at those coordinates newSceneGameObject.transform.position = new Vector3((float)entity.X, (float)entity.Y, (float)entity.Z); } // if the token is null, it means there are no more segments left to query token = queryResult.ContinuationToken; } while (token != null); }
在 TableToScene 類別之外,您必須定義應用程式用來序列化和還原序列化 資料表實體的類別。
/// <summary> /// This objects is used to serialize and deserialize the Azure Table Entity /// </summary> [System.Serializable] public class AzureTableEntity : TableEntity { public AzureTableEntity(string partitionKey, string rowKey) : base(partitionKey, rowKey) { } public AzureTableEntity() { } public string Type { get; set; } public double X { get; set; } public double Y { get; set; } public double Z { get; set; } }
請務必先 儲存 ,再返回 Unity 編輯器。
從 [階層] 面板按一下[主要相機],使其屬性會出現在Inspector中。
開啟 [腳本 ] 資料夾後,選取 腳本 TableToScene 檔案 ,然後將它拖曳到 主要相機。 結果應如下所示:
第 10 章 - 在桌面 Unity 專案中建立 CloudScene 類別
您需要建立的第二個腳本是 CloudScene,負責:
註冊滑鼠左鍵事件,讓使用者在場景周圍拖曳物件。
從這個 Unity 場景序列化物件資料,並將其傳送至 Azure 函式應用程式。
若要建立第二個腳本:
在 [腳本 ] 資料夾內按一下滑鼠右鍵,按一下 [ 建立]、 [C# 腳本]。 將腳本命名為 CloudScene
新增下列命名空間:
using Newtonsoft.Json; using System.Collections; using System.Text; using System.Threading.Tasks; using UnityEngine; using UnityEngine.Networking;
插入下列變數:
/// <summary> /// Allows this class to behave like a singleton /// </summary> public static CloudScene instance; /// <summary> /// Insert here you Azure Function Url /// </summary> private string azureFunctionEndpoint = "--Insert here you Azure Function Endpoint--"; /// <summary> /// Flag for object being moved /// </summary> private bool gameObjHasMoved; /// <summary> /// Transform of the object being dragged by the mouse /// </summary> private Transform gameObjHeld; /// <summary> /// Class hosted in the TableToScene script /// </summary> private AzureTableEntity azureTableEntity;
將azureFunctionEndpoint值取代為您在 Azure 函式App Service Azure 入口網站中找到的 Azure 函式應用程式 URL,如下圖所示:
現在新增 Start () 和 Awake () 方法來初始化 類別。
/// <summary> /// Triggers before initialization /// </summary> void Awake() { // static instance of this class instance = this; } /// <summary> /// Use this for initialization /// </summary> void Start() { // initialise an AzureTableEntity azureTableEntity = new AzureTableEntity(); }
在 Update () 方法中,新增下列程式碼,以偵測滑鼠輸入和拖曳,進而在場景中移動 GameObjects。 如果使用者已拖放物件,它會將物件的名稱和座標傳遞至 UpdateCloudScene () 方法,這會呼叫 Azure 函式 App Service,這會更新 Azure 資料表並觸發通知。
/// <summary> /// Update is called once per frame /// </summary> void Update() { //Enable Drag if button is held down if (Input.GetMouseButton(0)) { // Get the mouse position Vector3 mousePosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10); Vector3 objPos = Camera.main.ScreenToWorldPoint(mousePosition); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; // Raycast from the current mouse position to the object overlapped by the mouse if (Physics.Raycast(ray, out hit)) { // update the position of the object "hit" by the mouse hit.transform.position = objPos; gameObjHasMoved = true; gameObjHeld = hit.transform; } } // check if the left button mouse is released while holding an object if (Input.GetMouseButtonUp(0) && gameObjHasMoved) { gameObjHasMoved = false; // Call the Azure Function that will update the appropriate Entity in the Azure Table // and send a Notification to all subscribed Apps Debug.Log("Calling Azure Function"); StartCoroutine(UpdateCloudScene(gameObjHeld.name, gameObjHeld.position.x, gameObjHeld.position.y, gameObjHeld.position.z)); } }
現在新增 UpdateCloudScene () 方法,如下所示:
private IEnumerator UpdateCloudScene(string objName, double xPos, double yPos, double zPos) { WWWForm form = new WWWForm(); // set the properties of the AzureTableEntity azureTableEntity.RowKey = objName; azureTableEntity.X = xPos; azureTableEntity.Y = yPos; azureTableEntity.Z = zPos; // Serialize the AzureTableEntity object to be sent to Azure string jsonObject = JsonConvert.SerializeObject(azureTableEntity); using (UnityWebRequest www = UnityWebRequest.Post(azureFunctionEndpoint, jsonObject)) { byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(jsonObject); www.uploadHandler = new UploadHandlerRaw(jsonToSend); www.uploadHandler.contentType = "application/json"; www.downloadHandler = new DownloadHandlerBuffer(); www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); string response = www.responseCode.ToString(); } }
儲存程式碼並返回 Unity
將 CloudScene 腳本拖曳至 主要相機。
從 [階層] 面板按一下[主要相機],使其屬性會出現在Inspector中。
開啟 [ 腳本 ] 資料夾後,選取 CloudScene 腳本,然後將它拖曳到 主要相機。 結果應如下所示:
第 11 章 - 將桌面專案建置至 UWP
此專案的 Unity 區段所需的所有專案現在都已完成。
流覽至 [建置設定] ([檔案>建置設定]) 。
從 [ 建置設定 ] 視窗中,按一下 [ 建置]。
檔案總管視窗隨即出現,提示您輸入要建置的位置。 按一下左上角的 [ 新增 資料夾]) ,並將其命名為 BUILDS,以建立新資料夾 (。
開啟新的 BUILDS 資料夾,然後再次) 使用 [新增 資料夾] 建立另一個資料夾 (,並將其命名 為NH_Desktop_App。
選取 NH_Desktop_App 。 按一下 [選取資料夾]。 專案需要一分鐘的時間才能建置。
在建置之後,檔案總管會顯示新專案的位置。 不過,您不需要開啟它,因為您需要先在接下來的章節中建立其他 Unity 專案。
第 12 章 - 設定 Mixed Reality Unity 專案
以下是使用混合實境進行開發的一般設定,因此是其他專案的良好範本。
開啟 Unity ,然後按一下 [ 新增]。
您現在必須提供 Unity 專案名稱,插入 UnityMRNotifHub。 請確定專案類型已設定為 3D。 將 [位置 ] 設定為適合您 (記住,較接近根目錄的較佳) 。 然後按一下 [ 建立專案]。
開啟 Unity 時,值得檢查預設 腳本編輯器 已設定為 Visual Studio。 移至[編輯>喜好設定],然後從新視窗流覽至[外部工具]。 將 外部腳本編輯器 變更為 Visual Studio 2017。 關閉 [喜好設定] 視窗。
接下來,移至 [檔案>建置設定],然後按一下 [切換平臺] 按鈕,將平臺切換為通用 Windows 平臺。
移至[檔案>組建設定],並確定:
目標裝置 設定為 [任何裝置]
針對Microsoft HoloLens,將[目標裝置] 設定為HoloLens。
組建類型 設定為 D3D
SDK 設定為 [最新安裝]
Visual Studio 版本 設定為 [最新安裝]
[建置並執行 ] 設定為 [本機電腦]
在這裡,值得儲存場景,並將它新增至組建。
選取 [ 新增開啟場景]來執行此動作。 隨即會出現儲存視窗。
為此建立新的資料夾,以及任何未來的場景,然後選取 [ 新增資料夾 ] 按鈕,以建立新的資料夾,將它命名為 Scenes。
開啟新建立 的 Scenes 資料夾,然後在 [ 檔案名: 文字] 欄位中,輸入 NH_MR_Scene,然後按 [ 儲存]。
其餘設定在 [建置設定] 中,現在應該保留為預設值。
在相同的視窗中,按一下 [ 播放程式設定 ] 按鈕,這會在 偵測器 所在的空間中開啟相關的面板。
在此面板中,需要驗證一些設定:
在 [ 其他設定] 索引 標籤中:
腳本執行時間版本 應該是 實驗 性 (.NET 4.6 對等)
腳本後端應該是.NET
API 相容性層級 應該是 .NET 4.6
在面板下方,在[XR 設定] (中找到 [發佈設定) ],勾選[支援的虛擬實境],確定已新增Windows Mixed Reality SDK
在 [ 發佈設定] 索引標籤的 [ 功能] 底下,檢查:
InternetClient
回到 [組建設定], Unity C# 專案 不再呈現灰色:勾選此旁邊的核取方塊。
完成這些變更後,請關閉 [建置設定] 視窗。
儲存場景和專案檔>儲存場景/檔案>儲存專案。
重要
如果您想要略過此專案的 Unity 設定 元件 (混合實境應用程式) ,並繼續直接進入程式碼,請隨意 下載此 .unitypackage、將其匯入您的專案作為 自訂套件,然後從 第 14 章繼續進行。 您仍然需要新增腳本元件。
第 13 章 - 匯入 Mixed Reality Unity 專案中的 DLL
您將使用適用于 Unity 的 Azure 儲存體程式庫 (,其使用適用于 Azure 的 .Net SDK) 。 請遵循此 連結,瞭解如何搭配 Unity 使用 Azure 儲存體。 Unity 中目前有已知問題,需要在匯入之後重新設定外掛程式。 本節中的這些步驟 (4 - 7,) 在 Bug 解決之後就不再需要。
若要將 SDK 匯入您自己的專案,請確定您已下載最新的 .unitypackage。 然後執行下列動作:
使用 [資產> 匯入套件自訂套件> ] 功能表選項,將您從上述下載的 .unitypackage 新增至 Unity。
在快顯的 [匯入 Unity 套件] 方塊中,您可以選取[外掛程式>儲存體] 底下的所有專案。
按一下 [ 匯 入] 按鈕,將專案新增至您的專案。
移至 [專案] 檢視中[外掛程式] 底下的 [儲存體] 資料夾,並只選取下列外掛程式:
- Microsoft.Data.Edm
- Microsoft.Data.OData
- Microsoft.WindowsAzure.Storage
- Newtonsoft.Json
- System.Spatial
選取 這些特定外掛程式 後, 取消核取[任何平臺 ],然後 取消核取[WSAPlayer ],然後按一下 [ 套用]。
注意
您要將這些特定外掛程式標示為只能在 Unity 編輯器中使用。 這是因為 WSA 資料夾中有不同版本的相同外掛程式,將在專案從 Unity 匯出之後使用。
在 [ 儲存體外掛程式] 資料夾中,只選取:
Microsoft.Data.Services.Client
核取 [平臺設定] 底下的 [不要處理]方塊,然後按一下 [套用]。
注意
您正在標示此外掛程式「不要處理」,因為 Unity 元件修補程式處理此外掛程式時發生困難。 即使未處理外掛程式,外掛程式仍可運作。
第 14 章 - 在混合實境 Unity 專案中建立 TableToScene 類別
TableToScene類別與第 9 章中所述的類別相同。 遵循 第 9 章中所述的相同程式,在混合實境 Unity 專案中建立相同的類別。
完成本章之後, 您的兩個 Unity 專案 都會在主相機上設定此類別。
第 15 章 - 在 Mixed Reality Unity 專案中建立 NotificationReceiver 類別
您需要建立的第二個腳本是 NotificationReceiver,負責:
- 在初始化時向通知中樞註冊應用程式。
- 接聽來自通知中樞的通知。
- 從收到的通知還原序列化物件資料。
- 根據還原序列化的資料,在場景中移動 GameObjects。
若要建立 NotificationReceiver 腳本:
在 [腳本 ] 資料夾內按一下滑鼠右鍵,按一下 [ 建立]、 [C# 腳本]。 將腳本命名為 NotificationReceiver。
按兩下腳本加以開啟。
新增下列命名空間:
//using Microsoft.WindowsAzure.Messaging; using Newtonsoft.Json; using System; using System.Collections; using UnityEngine; #if UNITY_WSA_10_0 && !UNITY_EDITOR using Windows.Networking.PushNotifications; #endif
插入下列變數:
/// <summary> /// allows this class to behave like a singleton /// </summary> public static NotificationReceiver instance; /// <summary> /// Value set by the notification, new object position /// </summary> Vector3 newObjPosition; /// <summary> /// Value set by the notification, object name /// </summary> string gameObjectName; /// <summary> /// Value set by the notification, new object position /// </summary> bool notifReceived; /// <summary> /// Insert here your Notification Hub Service name /// </summary> private string hubName = " -- Insert the name of your service -- "; /// <summary> /// Insert here your Notification Hub Service "Listen endpoint" /// </summary> private string hubListenEndpoint = "-Insert your Notification Hub Service Listen endpoint-";
以您的通知中樞服務名稱取代 hubName 值,並以在 Azure 入口網站的 [存取原則] 索引標籤 Azure 通知中樞服務中找到的端點值取代 hubName 值, (請參閱下圖) 。
現在新增 Start () 和 Awake () 方法來初始化 類別。
/// <summary> /// Triggers before initialization /// </summary> void Awake() { // static instance of this class instance = this; } /// <summary> /// Use this for initialization /// </summary> void Start() { // Register the App at launch InitNotificationsAsync(); // Begin listening for notifications StartCoroutine(WaitForNotification()); }
新增 WaitForNotification 方法,以允許應用程式從通知中樞程式庫接收通知,而不會與主執行緒衝突:
/// <summary> /// This notification listener is necessary to avoid clashes /// between the notification hub and the main thread /// </summary> private IEnumerator WaitForNotification() { while (true) { // Checks for notifications each second yield return new WaitForSeconds(1f); if (notifReceived) { // If a notification is arrived, moved the appropriate object to the new position GameObject.Find(gameObjectName).transform.position = newObjPosition; // Reset the flag notifReceived = false; } } }
下列方法 InitNotificationAsync () 會在初始化時向通知中樞服務註冊應用程式。 程式碼會標記為批註,因為 Unity 將無法建置專案。 當您在 Visual Studio 中匯入 Azure 傳訊 Nuget 套件時,將會移除批註。
/// <summary> /// Register this application to the Notification Hub Service /// </summary> private async void InitNotificationsAsync() { // PushNotificationChannel channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); // NotificationHub hub = new NotificationHub(hubName, hubListenEndpoint); // Registration result = await hub.RegisterNativeAsync(channel.Uri); // If registration was successful, subscribe to Push Notifications // if (result.RegistrationId != null) // { // Debug.Log($"Registration Successful: {result.RegistrationId}"); // channel.PushNotificationReceived += Channel_PushNotificationReceived; // } }
下列處理常式 Channel_PushNotificationReceived () 會在每次收到通知時觸發。 它會還原序列化通知,這會是已在傳統型應用程式上移動的 Azure 資料表實體,然後將 MR 場景中的對應 GameObject 移至相同的位置。
重要
程式碼會加上批註,因為程式碼會參考 Azure 傳訊程式庫,您將在 Visual Studio 中使用 Nuget 套件管理員建置 Unity 專案之後新增此程式庫。 因此,除非將 Unity 專案標記為批註,否則 Unity 專案將無法建置。請注意,您應該建置專案,然後想要返回 Unity,您必須 重新批註 該程式碼。
///// <summary> ///// Handler called when a Push Notification is received ///// </summary> //private void Channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args) //{ // Debug.Log("New Push Notification Received"); // // if (args.NotificationType == PushNotificationType.Raw) // { // // Raw content of the Notification // string jsonContent = args.RawNotification.Content; // // // Deserialise the Raw content into an AzureTableEntity object // AzureTableEntity ate = JsonConvert.DeserializeObject<AzureTableEntity>(jsonContent); // // // The name of the Game Object to be moved // gameObjectName = ate.RowKey; // // // The position where the Game Object has to be moved // newObjPosition = new Vector3((float)ate.X, (float)ate.Y, (float)ate.Z); // // // Flag thats a notification has been received // notifReceived = true; // } //}
請記得在返回 Unity 編輯器之前儲存您的變更。
從 [階層] 面板按一下[主要相機],使其屬性會出現在Inspector中。
開啟 [ 腳本 ] 資料夾後,選取 NotificationReceiver 腳本,並將其拖曳至 主要相機。 結果應如下所示:
注意
如果您要針對Microsoft HoloLens進行此開發,您必須更新主要相機的相機元件,以便:
- 清除旗標:純色
- 背景:黑色
第 16 章 - 將Mixed Reality專案建置至 UWP
本章與上一個專案的建置程式相同。 此專案的 Unity 區段一切都已完成,因此是時候從 Unity 建置它。
流覽至 [建置設定] ( [檔案>建置設定] ) 。
從 [ 建置設定 ] 功能表中,確定 已勾選 Unity C# 專案* (,這可讓您在建置) 之後編輯此專案中的腳本。
完成此動作之後,按一下 [建置]。
檔案總管視窗隨即出現,提示您輸入要建置的位置。 按一下左上角的 [ 新增 資料夾]) ,並將其命名為 BUILDS,以建立新資料夾 (。
開啟新的 BUILDS 資料夾,然後再次使用 [ 新增 (資料夾]) 建立另一個資料夾,並將其命名 為NH_MR_App。
選取 NH_MR_App 。 按一下 [選取資料夾]。 專案需要一分鐘的時間才能建置。
在建置之後,檔案總管視窗會在新專案的位置開啟。
第 17 章 - 將 NuGet 套件新增至 UnityMRNotifHub 解決方案
警告
請記住,一旦您新增下列 NuGet 套件 (,並在下一 章) 取消批註程式碼之後,在 Unity 專案內重新開啟程式碼時,程式碼就會顯示錯誤。 如果您想要在 Unity 編輯器中返回並繼續編輯,則需要批註該錯誤的程式碼,然後在稍後重新批註,一旦您回到 Visual Studio。
完成混合實境建置之後,請流覽至您所建置的混合實境專案,然後按兩下該資料夾中的方案 (.sln) 檔案,以使用 Visual Studio 2017 開啟您的方案。 您現在必須新增 WindowsAzure.Messaging.managed NuGet 套件;這是用來從通知中樞接收通知的程式庫。
若要匯入 NuGet 套件:
在方案總管中,以滑鼠右鍵按一下您的解決方案
按一下 [管理 NuGet 套件]。
選取 [ 流覽] 索引標籤,然後搜尋 WindowsAzure.Messaging.managed。
選取結果 (,如下所示) ,然後在右側的視窗中,選取 [專案] 旁的核取方塊。 這會在 Project旁邊的核取方塊中加上核取方塊,以及 Assembly-CSharp 和 UnityMRNotifHub 專案旁的核取方塊。
最初提供的版本 可能與 這個專案不相容。 因此,按一下 [ 版本] 旁的下拉式功能表,然後按一下 [版本 0.1.7.9],然後按一下 [ 安裝]。
您現在已完成安裝 NuGet 套件。 尋找您在 NotificationReceiver 類別中輸入的批註程式碼,並移除批註。
第 18 章 - 編輯 UnityMRNotifHub 應用程式,NotificationReceiver 類別
在新增 NuGet 套件之後,您必須 取消批註NotificationReceiver 類別內的一些程式碼。
這包括:
頂端的命名空間:
using Microsoft.WindowsAzure.Messaging;
InitNotificationsAsync () 方法內的所有程式碼:
/// <summary> /// Register this application to the Notification Hub Service /// </summary> private async void InitNotificationsAsync() { PushNotificationChannel channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync(); NotificationHub hub = new NotificationHub(hubName, hubListenEndpoint); Registration result = await hub.RegisterNativeAsync(channel.Uri); // If registration was successful, subscribe to Push Notifications if (result.RegistrationId != null) { Debug.Log($"Registration Successful: {result.RegistrationId}"); channel.PushNotificationReceived += Channel_PushNotificationReceived; } }
警告
上述程式碼有批註:請確定您不小心 取消批 注 (批註,因為如果您有!) ,程式碼將不會編譯。
最後, Channel_PushNotificationReceived 事件:
/// <summary> /// Handler called when a Push Notification is received /// </summary> private void Channel_PushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args) { Debug.Log("New Push Notification Received"); if (args.NotificationType == PushNotificationType.Raw) { // Raw content of the Notification string jsonContent = args.RawNotification.Content; // Deserialize the Raw content into an AzureTableEntity object AzureTableEntity ate = JsonConvert.DeserializeObject<AzureTableEntity>(jsonContent); // The name of the Game Object to be moved gameObjectName = ate.RowKey; // The position where the Game Object has to be moved newObjPosition = new Vector3((float)ate.X, (float)ate.Y, (float)ate.Z); // Flag thats a notification has been received notifReceived = true; } }
使用這些未批註後,請確定您儲存,然後繼續進行下一章。
第 19 章 - 將混合實境專案與市集應用程式產生關聯
您現在必須將 混合實境 專案與您在實驗室開始時所建立的市集應用程式產生關聯。
開啟解決方案。
以滑鼠右鍵按一下 [方案總管] 面板中的 [UWP 應用程式專案]、移至 [市集] 和 [將應用程式與市集建立關聯...]。
新的視窗隨即出現,稱為將 您的應用程式與 Windows 市集建立關聯。 按一下 [下一步] 。
它會載入與您登入之帳戶相關聯的所有應用程式。 如果您未登入您的帳戶,您可以在此頁面 登入 。
尋找您在本教學課程開頭建立的 市集應用程式名稱 ,然後加以選取。 然後按一下 [下一步] 。
按一下 [關聯]。
您的應用程式現在已與市集應用程式 相關聯 。 這是啟用通知的必要專案。
第 20 章 - 部署 UnityMRNotifHub 和 UnityDesktopNotifHub 應用程式
這一章可能會讓兩個人更容易,因為結果會包含兩個應用程式執行、一個在您的電腦桌面上執行,另一個是在沉浸式頭戴式裝置內執行。
沉浸式頭戴裝置應用程式正在等候接收對場景的變更 (本機 GameObjects) 的位置變更,而傳統型應用程式將會變更其本機場景 (位置變更) ,這會共用給 MR 應用程式。 請先部署 MR 應用程式,後面接著傳統型應用程式,以便接收者開始接聽。
若要在本機電腦上部署 UnityMRNotifHub 應用程式:
在Visual Studio 2017中開啟UnityMRNotifHub應用程式的解決方案檔案。
在 [解決方案平臺]中,選取 [x86]、[本機電腦]。
在 [ 方案組態 ] 中,選取 [ 偵錯]。
移至 [建置] 功能表 ,然後按一下 [ 部署方案 ] 以側載應用程式到您的電腦。
您的應用程式現在應該會出現在已安裝的應用程式清單中,準備好啟動。
若要在本機電腦上部署 UnityDesktopNotifHub 應用程式:
在Visual Studio 2017中開啟UnityDesktopNotifHub應用程式的解決方案檔案。
在 [解決方案平臺]中,選取 [x86]、[本機電腦]。
在 [ 方案組態 ] 中,選取 [ 偵錯]。
移至 [建置] 功能表 ,然後按一下 [ 部署方案 ] 以側載應用程式到您的電腦。
您的應用程式現在應該會出現在已安裝的應用程式清單中,準備好啟動。
啟動混合實境應用程式,後面接著傳統型應用程式。
執行這兩個應用程式後,使用滑鼠左鍵) ,在桌面場景中移動物件 (。 這些位置變更將會在本機進行、序列化,並傳送至函式 App Service。 函式 App Service 接著會隨著通知中樞更新資料表。 收到更新之後,通知中樞會將更新的資料直接傳送到所有已註冊的應用程式 (,在此案例中,沉浸式頭戴裝置應用程式) ,然後還原序列化傳入資料,然後將新的位置資料套用至本機物件,並將它們移至場景。
您已完成 Azure 通知中樞應用程式
恭喜,您已建置混合實境應用程式,利用 Azure 通知中樞服務並允許應用程式之間的通訊。
額外練習
練習 1
您可以瞭解如何變更 GameObjects 的色彩,並將該通知傳送給檢視場景的其他應用程式?
練習 2
您可以將 GameObjects 的移動新增至 MR 應用程式,並在傳統型應用程式中查看更新的場景嗎?