這是老版本的教程,為了不耽誤大家的時間,請直接看原文,本文僅供參考哦!原文鏈接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/holograms_101
這篇文章將通過一個完整的實例來了解設備的核心特性,包括凝視,手勢,聲音輸入和空間聲音與空間映射。
先決條件
1.一個 Windows 10 PC 并安裝有相應的軟件tools installed..
2. 開發者模式的HoloLensconfigured for development. .
項目文件
1.下載此項目所需文件files。
2.將其保存在桌面或者其他易于找到的位置, 保持文件名為 Origami.
章節 1.“Holo”world?
? ? ?1設置Unity。
? ? ?2制作全息對象。
? ? ?3看到你做的全息對象。
- 打開 Unity.
- 選擇?Open.
- 選擇本地項目?Origami?文件夾
- 選擇?Origami?點擊?.
- 由于 Origami項目中不含有場景, 需要將默認的場景保存成項目場景: 打開File / Save Scene As.
- 將新場景命名為 Origami?然后點擊保存按鈕.
設置主相機
- 在Hierarchy 面板中, 選擇Main Camera.
- 在Inspector?設置 transform position 為?0,0,0.
- 找到Clear Flags?屬性, 打開下拉列表將?Skybox?改為Solid color.
- 點擊?Background?的顏色選擇器.
- 設置?R, G, B, ?A?都為?0.
配置場景
- 在Hierarchy 面板中, 點擊Create?-》?Create Empty.
- 右擊 新GameObject?為它重新命名為?OrigamiCollection.
- 在 Project 面板中選擇Holograms 文件夾,并雙擊打開:
- 拖拽Stage?到 Hierarchy面板中 ,使其成為?OrigamiCollection的子對象.
- 同理拖拽Sphere1
- 同理拖拽?Sphere2
- 刪除Hierarchy 面板中的Directional Light
- 從 Holograms?文件夾中, 拖拽?Lights?到Hierarchy面板中.
- 在Hierarchy中, 選中?OrigamiCollection.
- 在Inspector面板中, 設置其transform position 為0, -0.5, 2.0.
- 點擊Play?按鈕 來預覽你的全息對象.
- 你會在你的預覽窗口看到你的Origami 對象.
- 再次點擊?Play?按鈕停止預覽模式.
將項目從 Unity 導出到Visual Studio
- 在Unity中選擇File > Build Settings.
- ?在Platform?列表下選擇?Windows Store 然后點擊Switch Platform.
- 設置?SDK?為?Universal 10?,設置?Build Type?為D3D.
- 勾選?Unity C# Projects.
- 點擊?Add Open Scenes?來添加場景.
- 點擊?Build.
- 創建一個新的文件夾命名為 "App".
- 單擊?App 文件夾.
- ?選中此文件夾.
- Unity發布完成后, 一個新的 File Explorer 窗口將出現.
- 打開?App?文件夾.
- 雙擊打開Origami.sln.
- 在 Visual Studio上部工具欄中, 將 Debug 設置為?Release?,將 ARM 變為?X86.
- 點擊 Device button旁邊的箭頭, 然后選擇?Remote Device.
- 設置?Address?為你的hololens的 IP 地址 . 如果你不知道你的設備的IP 地址, 開啟hololens,選擇?Settings > Network & Internet > Advanced Options?查看或者詢問 Cortana "Hey Cortana, What's my IP address?"
- 將?Authentication Mode?設置為?Universal.
- 點擊?Select
- 點擊?Debug > Start Without debugging?或者點擊?Ctrl + F5. 如果這是你第一次發布應用到hololens, 你需要配對,具體需要輸入設備的PIN碼,在設置-》update-》for developers-》paired devices中查看。 pair it with Visual Studio.
- ?然后Origami項目開始發布部署到你的設備上并運行 .
- 請戴上你的hololens來欣賞你發布的全息應用吧.
章節 2.Gaze 凝視
這一章將介紹hololens交互的三大方式的第一種,凝視
目標
- 使用一個光標來可視化你的凝視點.
說明
- 回到 Unity 項目, 如果 Build Settings 窗口還開著請把它關掉 .
- 在 Project 面板中選擇Holograms文件夾.
- 拖拽 Cursor 對象 到 Hierarchy 面板 的根節點下.
- ?雙擊Cursor 對象近距離查看、.
- 在 Project 面板下右擊Scripts 文件夾.
- ?點擊Create sub-menu.
- ?選擇C# Script.
- ?給腳本命名 WorldCursor
- ?選擇 Hierarchy? 面板中的Cursor 對象.
- 拖拽 WorldCursor 腳本到 Inspector 面板中.
- 雙擊WorldCursor 腳本用 Visual Studio打開.
- ?復制粘貼以下代碼到WorldCursor.cs 然后保存.


using UnityEngine;public class WorldCursor : MonoBehaviour {private MeshRenderer meshRenderer;// Use this for initializationvoid Start(){// Grab the mesh renderer that's on the same object as this script.meshRenderer = this.gameObject.GetComponentInChildren<MeshRenderer>();}// Update is called once per framevoid Update(){// Do a raycast into the world based on the user's// head position and orientation.var headPosition = Camera.main.transform.position;var gazeDirection = Camera.main.transform.forward;RaycastHit hitInfo;if (Physics.Raycast(headPosition, gazeDirection, out hitInfo)){// If the raycast hit a hologram...// Display the cursor mesh.meshRenderer.enabled = true;// Move the cursor to the point where the raycast hit.this.transform.position = hitInfo.point;// Rotate the cursor to hug the surface of the hologram.this.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);}else{// If the raycast did not hit a hologram, hide the cursor mesh.meshRenderer.enabled = false;}} }
- ?從新發布APP,通過File > Build Settings.從文件>構建設置重建應用程序。
- ? 返回到以前用于部署到HoloLens的Visual Studio解決方案
- 出現提示時,選擇“重新加載所有”。
- 單擊調試 - >開始無調試或按Ctrl + F5。
- 現在看看場景,注意光標如何與對象的形狀進行交互。
章節 3.手勢
?這一章,將添加手勢支持,當用戶選擇場景中的紙球時,通過Unity設置有物理重力的紙球會掉落。
目標
- 通過手勢控制場景中的全息對象.
說明
- ?在Scripts 文件夾, 創建一個新的腳本并命名為 GazeGestureManager.
- ?拖拽GazeGestureManager 腳本到Hierarchy面板中的 OrigamiCollection 對象上? .
- 用VS打開GazeGestureManager 腳本,將以下代碼粘貼其中:


using UnityEngine; using UnityEngine.VR.WSA.Input;public class GazeGestureManager : MonoBehaviour {public static GazeGestureManager Instance { get; private set; }// Represents the hologram that is currently being gazed at.public GameObject FocusedObject { get; private set; }GestureRecognizer recognizer;// Use this for initializationvoid Awake(){Instance = this;// Set up a GestureRecognizer to detect Select gestures.recognizer = new GestureRecognizer();recognizer.TappedEvent += (source, tapCount, ray) =>{// Send an OnSelect message to the focused object and its ancestors.if (FocusedObject != null){FocusedObject.SendMessageUpwards("OnSelect");}};recognizer.StartCapturingGestures();}// Update is called once per framevoid Update(){// Figure out which hologram is focused this frame.GameObject oldFocusObject = FocusedObject;// Do a raycast into the world based on the user's// head position and orientation.var headPosition = Camera.main.transform.position;var gazeDirection = Camera.main.transform.forward;RaycastHit hitInfo;if (Physics.Raycast(headPosition, gazeDirection, out hitInfo)){// If the raycast hit a hologram, use that as the focused object.FocusedObject = hitInfo.collider.gameObject;}else{// If the raycast did not hit a hologram, clear the focused object.FocusedObject = null;}// If the focused object changed this frame,// start detecting fresh gestures again.if (FocusedObject != oldFocusObject){recognizer.CancelGestures();recognizer.StartCapturingGestures();}} }
- ?在Scripts 文件夾下創建一個新的腳本命名為 SphereCommands.
- ?展開Hierarchy面板中的OrigamiCollection 對象.
- ?拖拽SphereCommands 腳本到 Sphere1 對象上.
- ?拖拽SphereCommands 腳本到 Sphere2 對象上.
- 用VS打開這個腳本并編輯,將以下代碼復制粘貼到其中:


using UnityEngine;public class SphereCommands : MonoBehaviour {// Called by GazeGestureManager when the user performs a Select gesturevoid OnSelect(){// If the sphere has no Rigidbody component, add one to enable physics.if (!this.GetComponent<Rigidbody>()){var rigidbody = this.gameObject.AddComponent<Rigidbody>();rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;}} }
- 再一次導出,發布部署 app 到你的 HoloLens.
- 看著一個球.
- 使用手勢點擊觀看其下落效果.
章節 4.語音
這一章將添加兩個語音指令,“Reset world”來返回初始場景狀態,“Drop sphere”使得球體下落。
目標
- 添加語音指令.
- 創建一個對語音指令做出反應的全息對象.
說明
- ?在Scripts 文件夾下, 創建一個新的腳本并命名為 SpeechManager.
- ?拖拽SpeechManager 腳本到 OrigamiCollection 對象上
- ?用VS打開SpeechManager 腳本.
- 復制粘貼以下代碼到 SpeechManager.cs 中然后保存:


using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Windows.Speech;public class SpeechManager : MonoBehaviour {KeywordRecognizer keywordRecognizer = null;Dictionary<string, System.Action> keywords = new Dictionary<string, System.Action>();// Use this for initializationvoid Start(){keywords.Add("Reset world", () =>{// Call the OnReset method on every descendant object.this.BroadcastMessage("OnReset");});keywords.Add("Drop Sphere", () =>{var focusObject = GazeGestureManager.Instance.FocusedObject;if (focusObject != null){// Call the OnDrop method on just the focused object.focusObject.SendMessage("OnDrop");}});// Tell the KeywordRecognizer about our keywords.keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray());// Register a callback for the KeywordRecognizer and start recognizing!keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;keywordRecognizer.Start();}private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args){System.Action keywordAction;if (keywords.TryGetValue(args.text, out keywordAction)){keywordAction.Invoke();}} }
- ?用VS打開SphereCommands 腳本.
- 更新為如下代碼:


using UnityEngine;public class SphereCommands : MonoBehaviour {Vector3 originalPosition;// Use this for initializationvoid Start(){// Grab the original local position of the sphere when the app starts.originalPosition = this.transform.localPosition;}// Called by GazeGestureManager when the user performs a Select gesturevoid OnSelect(){// If the sphere has no Rigidbody component, add one to enable physics.if (!this.GetComponent<Rigidbody>()){var rigidbody = this.gameObject.AddComponent<Rigidbody>();rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;}}// Called by SpeechManager when the user says the "Reset world" commandvoid OnReset(){// If the sphere has a Rigidbody component, remove it to disable physics.var rigidbody = this.GetComponent<Rigidbody>();if (rigidbody != null){DestroyImmediate(rigidbody);}// Put the sphere back into its original local position.this.transform.localPosition = originalPosition;}// Called by SpeechManager when the user says the "Drop sphere" commandvoid OnDrop(){// Just do the same logic as a Select gesture. OnSelect();} }
- 從新導出發布部署APP到 HoloLens.
- ?看著其中一個球,說"Drop Sphere".
- ?說"Reset World" 使他們回到初始的位置.
章節 5.空間聲音
這一章,我們會為APP添加音樂,在特定操作上觸發聲音效果,我們將使用spatial sound特性給聲音一個3D空間位置。
目標
- 在你的世界中聽見全息對象.
說明
- ?在Unity 選擇 Edit > Project Settings > Audio
- 在右側的 Inspector 面板中, 找到 Spatializer Plugin 設置然后選擇 MS HRTF Spatializer.
- 在 Project 面板下從Holograms文件夾, 拖拽 Ambience 對象到 到 Hierarchy 面板下的OrigamiCollection 對象上.
- ?選擇OrigamiCollection? 對象,在右側的Inspector面板 中找到Audio Source 組件. 改變以下屬性值:
- 選擇 Spatialize property.
- ?選擇Play On Awake.
- ?將Spatial Blend 改成 3D
- ?選擇Loop property.
- 展開 3D Sound Settings,? 在Doppler Level 輸入0.1.
- ?設置Volume Rolloff 為 Custom Rolloff.
- ?在Scripts 文件夾下, 創建一個新的腳本并命名為 SphereSounds.
- ?拖拽SphereSounds 腳本到 Sphere1 和 Sphere2 對象上.
- ?用VS打開SphereSounds 腳本, 更新為以下代碼并保存.


using UnityEngine;public class SphereSounds : MonoBehaviour {AudioSource audioSource = null;AudioClip impactClip = null;AudioClip rollingClip = null;bool rolling = false;void Start(){// Add an AudioSource component and set up some defaultsaudioSource = gameObject.AddComponent<AudioSource>();audioSource.playOnAwake = false;audioSource.spatialize = true;audioSource.spatialBlend = 1.0f;audioSource.dopplerLevel = 0.0f;audioSource.rolloffMode = AudioRolloffMode.Custom;// Load the Sphere sounds from the Resources folderimpactClip = Resources.Load<AudioClip>("Impact");rollingClip = Resources.Load<AudioClip>("Rolling");}// Occurs when this object starts colliding with another objectvoid OnCollisionEnter(Collision collision){// Play an impact sound if the sphere impacts strongly enough.if (collision.relativeVelocity.magnitude >= 0.1f){audioSource.clip = impactClip;audioSource.Play();}}// Occurs each frame that this object continues to collide with another objectvoid OnCollisionStay(Collision collision){Rigidbody rigid = this.gameObject.GetComponent<Rigidbody>();// Play a rolling sound if the sphere is rolling fast enough.if (!rolling && rigid.velocity.magnitude >= 0.01f){rolling = true;audioSource.clip = rollingClip;audioSource.Play();}// Stop the rolling sound if rolling slows down.else if (rolling && rigid.velocity.magnitude < 0.01f){rolling = false;audioSource.Stop();}}// Occurs when this object stops colliding with another objectvoid OnCollisionExit(Collision collision){// Stop the rolling sound if the object falls off and stops colliding.if (rolling){rolling = false;audioSource.Stop();}} }
- 保存腳本,返回到Unity中.
- 導出發布并部署 app 到你的 HoloLens.
- 移動遠近來感受聲音的變化.
章節 6.空間映射
現在我們將使用空間映射特性將游戲板放置在現實世界中的真實對象上。
目標
- 把你的現實世界變成一個虛擬世界.
- 把你的全息圖放在你想把它放置的位置.
步驟
- ?在Unity 中, 點擊Project 面板下的 Holograms 文件夾.
- 將 Spatial Mapping asset 拖拽到 Hierarchy面板的根節點.
- ?點擊Hierarchy 面板下的Spatial Mapping 對象? .
- 在右側的 Inspector 面板, 改變如下設置:
- 選擇 Draw Visual Meshes box.
- ?定位到Draw Material 然后點擊它右側的圓. 在頂部的搜索字段中鍵入“wireframe”。單擊結果,然后關閉窗口。執行此操作時,Draw Material的值應設置為線框.
- 導出,發布并將應用程序部署到您的HoloLens。 ??
- 當應用程序運行時,線框網格將覆蓋你的現實世界。
- 觀看滾動球體將如何從平臺掉落到地板上!
現在,我們將向您展示如何將OrigamiCollection移動到新位置:
- ?在Scripts 文件夾下, 創建一個新的腳本并命名為 TapToPlaceParent.
- ?在Hierarchy 面板下,展開 OrigamiCollection 然后選擇 Stage 對象.
- ?拖拽TapToPlaceParent 腳本到 Stage 對象上.
- ?用VS打開TapToPlaceParent 腳本, 更新為如下代碼:


using UnityEngine;public class TapToPlaceParent : MonoBehaviour {bool placing = false;// Called by GazeGestureManager when the user performs a Select gesturevoid OnSelect(){// On each Select gesture, toggle whether the user is in placing mode.placing = !placing;// If the user is in placing mode, display the spatial mapping mesh.if (placing){SpatialMapping.Instance.DrawVisualMeshes = true;}// If the user is not in placing mode, hide the spatial mapping mesh.else{SpatialMapping.Instance.DrawVisualMeshes = false;}}// Update is called once per framevoid Update(){// If the user is in placing mode,// update the placement to match the user's gaze.if (placing){// Do a raycast into the world that will only hit the Spatial Mapping mesh.var headPosition = Camera.main.transform.position;var gazeDirection = Camera.main.transform.forward;RaycastHit hitInfo;if (Physics.Raycast(headPosition, gazeDirection, out hitInfo,30.0f, SpatialMapping.PhysicsRaycastMask)){// Move this object's parent object to// where the raycast hit the Spatial Mapping mesh.this.transform.parent.position = hitInfo.point;// Rotate this object's parent object to face the user.Quaternion toQuat = Camera.main.transform.localRotation;toQuat.x = 0;toQuat.z = 0;this.transform.parent.rotation = toQuat;}}} }
- 導出,構建和部署應用程序.
- 現在,您現在應該能夠通過注視它,使用選擇手勢,然后移動到一個新的位置,并再次使用選擇手勢,將對象放在特定的位置。
章節 7.全息的樂趣
目標
- 顯示全息對象背后的世界入口的效果.
步驟
- 在 Project 面板下打開Holograms 文件夾:
- ?拖拽Underworld 到 Hierarchy 面板下成為 OrigamiCollection 的孩子.
- 在 Scripts 文件夾下, 創建一個新的腳本并命名為 HitTarget.
- ?在Hierarchy 面板下, 展開 OrigamiCollection.
- ?展開Stage 對象然后選擇 Target 對象 (blue fan).
- 拖拽HitTarget 腳本到 Target 對象上.
- ?用VS打開HitTarget 腳本, 更新為以下代碼:


using UnityEngine;public class HitTarget : MonoBehaviour {// These public fields become settable properties in the Unity editor.public GameObject underworld;public GameObject objectToHide;// Occurs when this object starts colliding with another objectvoid OnCollisionEnter(Collision collision){// Hide the stage and show the underworld.objectToHide.SetActive(false);underworld.SetActive(true);// Disable Spatial Mapping to let the spheres enter the underworld.SpatialMapping.Instance.MappingEnabled = false;} }
- 在Unity, 選擇 Target 對象.
- 在 Hit Target?組件中可見兩個公共屬性, 需要引用場景中的對象:
- 拖拽Hierarchy 面板下的 Underworld 對象到 Hit Target 組件下的 Underworld 屬性中.
- 拖拽Hierarchy 面板下的 Stage對象到 Hit Target 組件下的?Object to Hide 屬性中。
- 導出發布部署 app.
- ?將折紙集合放在地板上,然后使用選擇手勢使球體下降。
- 當球碰到目標(blue fan)時,將發生爆炸。收集將被隱藏,一個洞會出現。
原文鏈接:https://developer.microsoft.com/en-us/windows/holographic/holograms_101
如有翻譯上的錯誤請指正,謝謝