备注

混合现实学院教程的设计附带了 HoloLens (第一代) 和混合现实沉浸式耳机。The Mixed Reality Academy tutorials were designed with HoloLens (1st gen) and Mixed Reality Immersive Headsets in mind. 因此, 对于那些仍在寻找为这些设备进行开发的指导的开发人员来说, 我们认为这些教程是非常重要的。As such, we feel it is important to leave these tutorials in place for developers who are still looking for guidance in developing for those devices. 这些教程将 使用最新工具集或用于 HoloLens 2 的交互进行更新。These tutorials will not be updated with the latest toolsets or interactions being used for HoloLens 2. 将保留这些设备以继续使用支持的设备。They will be maintained to continue working on the supported devices. 将来会发布一系列新教程, 这些教程将演示如何针对 HoloLens 2 进行开发。There will be a new series of tutorials that will be posted in the future that will demonstrate how to develop for HoloLens 2. 此通知将在发布时通过指向这些教程的链接进行更新。This notice will be updated with a link to those tutorials when they are posted.


MR 要点 101:完成具有设备的项目MR Basics 101: Complete project with device


本教程将引导你完成 Unity 中内置的一个完整项目, 该项目演示了 HoloLens 上核心 Windows Mixed Reality 功能, 包括注视手势语音输入空间音效空间映射.This tutorial will walk you through a complete project, built in Unity, that demonstrates core Windows Mixed Reality features on HoloLens including gaze, gestures, voice input, spatial sound and spatial mapping.

教程大约需要1小时才能完成。The tutorial will take approximately 1 hour to complete.

设备支持Device support

摘要Course HoloLensHoloLens 沉浸式头戴显示设备Immersive headsets
MR 要点 101:完成具有设备的项目MR Basics 101: Complete project with device ✔️✔️

开始之前Before you start

系统必备Prerequisites

项目文件Project files

  • 下载项目所需的文件Download the files required by the project. 需要 Unity 2017.2 或更高版本。 Requires Unity 2017.2 or later.
    • 如果仍需要 Unity 5.6 支持, 请使用此版本If you still need Unity 5.6 support, please use this release.
    • 如果仍需要 Unity 5.5 支持, 请使用此版本If you still need Unity 5.5 support, please use this release.
    • 如果仍需要 Unity 5.4 支持, 请使用此版本If you still need Unity 5.4 support, please use this release.
  • 取消将文件存档到桌面或其他易于访问的位置。Un-archive the files to your desktop or other easy to reach location. 将文件夹名称保留为日式折纸Keep the folder name as Origami.

备注

如果要在下载之前查看源代码,可在 GitHub 上找到。If you want to look through the source code before downloading, it's available on GitHub.

第1章-"Holo" 世界Chapter 1 - "Holo" world

在本章中, 我们将设置第一个 Unity 项目, 并逐步完成生成和部署过程。In this chapter, we'll setup our first Unity project and step through the build and deploy process.

目标Objectives

  • 为全息版开发设置 Unity。Set up Unity for holographic development.
  • 制作全息影像。Make a hologram.
  • 查看您创建的全息影像。See a hologram that you made.

说明Instructions

  • 启动 Unity。Start Unity.
  • 选择 "打开"。Select Open.
  • 输入 "位置" 作为以前未存档的日式折纸文件夹。Enter location as the Origami folder you previously un-archived.
  • 选择 "日式折纸" 并单击 "选择文件夹"。Select Origami and click Select Folder.
  • 由于日式折纸项目不包含场景, 因此请使用将空的默认场景保存到新文件中:文件 / 另存为Since the Origami project does not contain a scene, save the empty default scene to a new file using: File / Save Scene As.
  • 将新场景命名为日式折纸, 并按 "保存" 按钮。Name the new scene Origami and press the Save button.

设置主虚拟摄像机Setup the main virtual camera

  • 在 "层次结构" 面板中, 选择 "主相机"。In the Hierarchy Panel, select Main Camera.
  • 检查器将其转换位置设置为0, 0, 0In the Inspector set its transform position to 0,0,0.
  • 找到 "清除标志" 属性, 然后将下拉列表中的Skybox更改为纯色Find the Clear Flags property, and change the dropdown from Skybox to Solid color.
  • 单击 "背景" 字段打开颜色选取器。Click on the Background field to open a color picker.
  • R、G、B 和 A设置为0Set R, G, B, and A to 0.

设置场景Setup the scene

  • 在 "层次结构" 面板中, 单击 "创建" 并创建空In the Hierarchy Panel, click on Create and Create Empty.
  • 右键单击新的 " GameObject ", 然后选择 "重命名"。Right-click the new GameObject and select Rename. 将 GameObject 重命名为OrigamiCollectionRename the GameObject to OrigamiCollection.
  • 从 " 项目" 面板 (展开 "资产" 并选择全息影像, 或双击 "项目" 面板中的 "全息影像" 文件夹):From the Holograms folder in the Project Panel (expand Assets and select Holograms or double click the Holograms folder in the Project Panel):
    • 阶段拖到层次结构中, 使其成为OrigamiCollection的子级。Drag Stage into the Hierarchy to be a child of OrigamiCollection.
    • Sphere1拖到层次结构中, 使其成为OrigamiCollection的子元素。Drag Sphere1 into the Hierarchy to be a child of OrigamiCollection.
    • Sphere2拖到层次结构中, 使其成为OrigamiCollection的子元素。Drag Sphere2 into the Hierarchy to be a child of OrigamiCollection.
  • 右键单击 "层次结构" 面板中的方向浅对象, 然后选择 "删除"。Right-click the Directional Light object in the Hierarchy Panel and select Delete.
  • 从 "全息影像" 文件夹中, 将灯光拖到层次结构面板的根。From the Holograms folder, drag Lights into the root of the Hierarchy Panel.
  • 层次结构中, 选择 " OrigamiCollection"。In the Hierarchy, select the OrigamiCollection.
  • 检查器中, 将转换位置设置为0、-0.5、2.0In the Inspector, set the transform position to 0, -0.5, 2.0.
  • 按下 Unity 中的 "播放" 按钮, 预览全息影像。Press the Play button in Unity to preview your holograms.
  • 预览窗口中应会显示日式折纸对象。You should see the Origami objects in the preview window.
  • 按第二次播放以停止预览模式。Press Play a second time to stop preview mode.

将项目从 Unity 导出到 Visual StudioExport the project from Unity to Visual Studio

  • 在 Unity 中, 选择 "文件 > 生成设置"。In Unity select File > Build Settings.

  • 选择 "平台" 列表中的 "通用 Windows 平台", 然后单击 "切换平台"。Select Universal Windows Platform in the Platform list and click Switch Platform.

  • SDK设置为通用 10 , 将类型设置为D3DSet SDK to Universal 10 and Build Type to D3D.

  • 检查Unity C#项目Check Unity C# Projects.

  • 单击 "添加打开的场景" 添加场景。Click Add Open Scenes to add the scene.

  • 单击“生成” 。Click Build.

  • 在出现的 "文件资源管理器" 窗口中, 创建一个名为 "App" 的新文件夹In the file explorer window that appears, create a New Folder named "App".

  • 单击应用文件夹Single click the App Folder.

  • 按 "选择文件夹"。Press Select Folder.

  • 当 Unity 完成后, 将显示文件资源管理器窗口。When Unity is done, a File Explorer window will appear.

  • 打开应用程序文件夹。Open the App folder.

  • 打开 (双击) "日式折纸"。Open (double click) Origami.sln.

  • 使用 Visual Studio 中的顶部工具栏, 将目标从 "调试" 更改为 "发布", 将 "从 ARM" 更改为 " X86"。Using the top toolbar in Visual Studio, change the target from Debug to Release and from ARM to X86.

  • 单击 "设备" 按钮旁边的箭头, 并选择 "远程计算机" 以通过 wi-fi 进行部署。Click on the arrow next to the Device button, and select Remote Machine to deploy over Wi-Fi.

    • 地址设置为 HoloLens 的名称或 IP 地址。Set the Address to the name or IP address of your HoloLens. 如果你不知道设备 IP 地址, 请在 "设置" 中查找 " > 网络 & Internet > 高级选项 " 或 "我的 IP 地址是什么?"。If you do not know your device IP address, look in Settings > Network & Internet > Advanced Options or ask Cortana "Hey Cortana, What's my IP address?"
    • 如果 HoloLens 通过 USB 连接, 则可以选择 "设备通过 usb 进行部署"。If the HoloLens is attached over USB, you may instead select Device to deploy over USB.
    • 身份验证模式设置为 "通用"。Leave the Authentication Mode set to Universal.
    • 单击 "选择"Click Select
  • 单击 "调试" > "开始但不调试" 或按Ctrl + F5Click Debug > Start Without debugging or press Ctrl + F5. 如果这是首次部署到设备, 则需要将其与 Visual Studio 配对If this is the first time deploying to your device, you will need to pair it with Visual Studio.

  • 现在, 日式折纸项目将生成、部署到 HoloLens, 然后运行。The Origami project will now build, deploy to your HoloLens, and then run.

  • 放在你的 HoloLens 上, 并查看你的新全息影像。Put on your HoloLens and look around to see your new holograms.

第2章-注视Chapter 2 - Gaze

在本章中, 我们将介绍第三种与全息影像交互的方式--注视In this chapter, we are going to introduce the first of three ways of interacting with your holograms -- gaze.

目标Objectives

  • 使用全球锁定的光标直观显示注视。Visualize your gaze using a world-locked cursor.

说明Instructions

  • 返回到 Unity 项目, 并关闭 "生成设置" 窗口 (如果它仍处于打开状态)。Go back to your Unity project, and close the Build Settings window if it's still open.
  • 在 "项目" 面板中选择全息影像文件夹。Select the Holograms folder in the Project panel.
  • 光标对象拖到层次结构面板中的根级别。Drag the Cursor object into the Hierarchy panel at the root level.
  • 双击光标对象以详细查看它。Double-click on the Cursor object to take a closer look at it.
  • 右键单击 "项目" 面板中的 "脚本" 文件夹。Right-click on the Scripts folder in the Project panel.
  • 单击 "创建" 子菜单。Click the Create sub-menu.
  • 选择 C# "脚本"。Select C# Script.
  • 将脚本命名为WorldCursorName the script WorldCursor. 注意:该名称区分大小写。Note: The name is case-sensitive. 无需添加 .cs 扩展名。You do not need to add the .cs extension.
  • 选择 "层次结构" 面板中的光标对象。Select the Cursor object in the Hierarchy panel.
  • WorldCursor脚本拖放到检查器面板Drag and drop the WorldCursor script into the Inspector panel.
  • 双击WorldCursor脚本, 在 Visual Studio 中将其打开。Double-click the WorldCursor script to open it in Visual Studio.
  • 将此代码复制并粘贴到WorldCursor.cs , 并保存全部Copy and paste this code into WorldCursor.cs and Save All.
using UnityEngine;

public class WorldCursor : MonoBehaviour
{
    private MeshRenderer meshRenderer;

    // Use this for initialization
    void Start()
    {
        // Grab the mesh renderer that's on the same object as this script.
        meshRenderer = this.gameObject.GetComponentInChildren<MeshRenderer>();
    }

    // Update is called once per frame
    void 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;
        }
    }
}
  • 文件 > 生成设置重新生成应用。Rebuild the app from File > Build Settings.
  • 返回到以前用于部署到 HoloLens 的 Visual Studio 解决方案。Return to the Visual Studio solution previously used to deploy to your HoloLens.
  • 出现提示时, 选择 "全部重新加载"。Select 'Reload All' when prompted.
  • 单击 "调试-> 启动但不调试" 或按Ctrl + F5Click Debug -> Start Without debugging or press Ctrl + F5.
  • 现在, 浏览场景并注意光标如何与对象的形状交互。Now look around the scene and notice how the cursor interacts with the shape of objects.

第3章-手势Chapter 3 - Gestures

在本章中, 我们将添加对手势的支持。In this chapter, we'll add support for gestures. 当用户选择某一回形针时, 我们将使用 Unity 的物理引擎开启重心来使球落在一起。When the user selects a paper sphere, we'll make the sphere fall by turning on gravity using Unity's physics engine.

目标Objectives

  • 用选择手势控制全息影像。Control your holograms with the Select gesture.

说明Instructions

首先, 我们将创建一个脚本, 然后可以检测选择的手势。We'll start by creating a script then can detect the Select gesture.

  • 在 "脚本" 文件夹中, 创建一个名为GazeGestureManager的脚本。In the Scripts folder, create a script named GazeGestureManager.
  • GazeGestureManager脚本拖到层次结构中的OrigamiCollection对象。Drag the GazeGestureManager script onto the OrigamiCollection object in the Hierarchy.
  • 在 Visual Studio 中打开GazeGestureManager脚本, 并添加以下代码:Open the GazeGestureManager script in Visual Studio and add the following code:
using UnityEngine;
using UnityEngine.XR.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 initialization
    void Awake()
    {
        Instance = this;

        // Set up a GestureRecognizer to detect Select gestures.
        recognizer = new GestureRecognizer();
        recognizer.Tapped += (args) =>
        {
            // Send an OnSelect message to the focused object and its ancestors.
            if (FocusedObject != null)
            {
                FocusedObject.SendMessageUpwards("OnSelect", SendMessageOptions.DontRequireReceiver);
            }
        };
        recognizer.StartCapturingGestures();
    }

    // Update is called once per frame
    void 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 文件夹中创建另一个脚本, 这一次名为SphereCommandsCreate another script in the Scripts folder, this time named SphereCommands.
  • 展开层次结构视图中的OrigamiCollection对象。Expand the OrigamiCollection object in the Hierarchy view.
  • SphereCommands脚本拖到 "层次结构" 面板中的 " Sphere1 " 对象。Drag the SphereCommands script onto the Sphere1 object in the Hierarchy panel.
  • SphereCommands脚本拖到 "层次结构" 面板中的 " Sphere2 " 对象。Drag the SphereCommands script onto the Sphere2 object in the Hierarchy panel.
  • 在 Visual Studio 中打开脚本进行编辑, 并将默认代码替换为以下代码:Open the script in Visual Studio for editing, and replace the default code with this:
using UnityEngine;

public class SphereCommands : MonoBehaviour
{
    // Called by GazeGestureManager when the user performs a Select gesture
    void 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;
        }
    }
}
  • 导出应用, 生成应用并将其部署到 HoloLens。Export, build and deploy the app to your HoloLens.
  • 查看球之一。Look at one of the spheres.
  • 执行 "选择手势" 并观看以下图面上的球。Perform the select gesture and watch the sphere drop onto the surface below.

第4章-语音Chapter 4 - Voice

在本章中, 我们将添加对两个语音命令的支持:"重置世界": 将已删除的球返回到其原始位置, 并将 "击落球" 设置为球落。In this chapter, we'll add support for two voice commands: "Reset world" to return the dropped spheres to their original location, and "Drop sphere" to make the sphere fall.

目标Objectives

  • 添加始终在后台侦听的语音命令。Add voice commands that always listen in the background.
  • 创建可响应语音命令的全息图。Create a hologram that reacts to a voice command.

说明Instructions

  • 在 "脚本" 文件夹中, 创建一个名为SpeechManager的脚本。In the Scripts folder, create a script named SpeechManager.
  • SpeechManager脚本拖到层次结构中的OrigamiCollection对象上Drag the SpeechManager script onto the OrigamiCollection object in the Hierarchy
  • 在 Visual Studio 中打开SpeechManager脚本。Open the SpeechManager script in Visual Studio.
  • 将此代码复制并粘贴到SpeechManager.cs , 并保存全部内容:Copy and paste this code into SpeechManager.cs and Save All:
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 initialization
    void 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", SendMessageOptions.DontRequireReceiver);
            }
        });

        // 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();
        }
    }
}
  • 在 Visual Studio 中打开SphereCommands脚本。Open the SphereCommands script in Visual Studio.
  • 按如下所示更新脚本以进行读取:Update the script to read as follows:
using UnityEngine;

public class SphereCommands : MonoBehaviour
{
    Vector3 originalPosition;

    // Use this for initialization
    void 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 gesture
    void 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" command
    void OnReset()
    {
        // If the sphere has a Rigidbody component, remove it to disable physics.
        var rigidbody = this.GetComponent<Rigidbody>();
        if (rigidbody != null)
        {
            rigidbody.isKinematic = true;
            Destroy(rigidbody);
        }

        // Put the sphere back into its original local position.
        this.transform.localPosition = originalPosition;
    }

    // Called by SpeechManager when the user says the "Drop sphere" command
    void OnDrop()
    {
        // Just do the same logic as a Select gesture.
        OnSelect();
    }
}
  • 导出应用, 生成应用并将其部署到 HoloLens。Export, build and deploy the app to your HoloLens.
  • 查看某一球, 说 "击落球"。Look at one of the spheres, and say "Drop Sphere".
  • 说 "重置世界", 将其返回到其初始位置。Say "Reset World" to bring them back to their initial positions.

第5章-空间音效Chapter 5 - Spatial sound

在本章中, 我们将向应用程序添加音乐, 并触发对某些操作的声音影响。In this chapter, we'll add music to the app, and then trigger sound effects on certain actions. 我们将使用空间音效为声音指定3d 空间中的特定位置。We'll be using spatial sound to give sounds a specific location in 3D space.

目标Objectives

  • 收听世界上的全息影像。Hear holograms in your world.

说明Instructions

  • 在 Unity 中从顶部菜单中选择 "编辑 > 项目设置 > 音频"In Unity select from the top menu Edit > Project Settings > Audio
  • 在右侧的检查器面板中, 找到 " Spatializer" 插件设置, 然后选择 " MS HRTF Spatializer"。In the Inspector Panel on the right side, find the Spatializer Plugin setting and select MS HRTF Spatializer.
  • 在 " 项目" 面板中, 将 "环境" 对象拖到 "层次结构" 面板中的OrigamiCollection对象上。From the Holograms folder in the Project panel, drag the Ambience object onto the OrigamiCollection object in the Hierarchy Panel.
  • 选择OrigamiCollection并在 "检查器" 面板中查找音频源组件。Select OrigamiCollection and find the Audio Source component in the Inspector panel. 更改这些属性:Change these properties:
    • 检查Spatialize属性。Check the Spatialize property.
    • 选中 "在唤醒状态播放"。Check the Play On Awake.
    • 通过将滑块一直拖到右侧, 将空间混合更改为三维Change Spatial Blend to 3D by dragging the slider all the way to the right. 移动滑块时, 值应从0更改为1。The value should change from 0 to 1 when you move the slider.
    • 检查循环属性。Check the Loop property.
    • 展开 "三维声音设置", 然后为 " Doppler" 级别输入0.1Expand 3D Sound Settings, and enter 0.1 for Doppler Level.
    • Volume Rolloff设置为对数 RolloffSet Volume Rolloff to Logarithmic Rolloff.
    • 最大距离设置为20Set Max Distance to 20.
  • 在 "脚本" 文件夹中, 创建一个名为SphereSounds的脚本。In the Scripts folder, create a script named SphereSounds.
  • SphereSounds拖放到层次结构中的Sphere1Sphere2对象。Drag and drop SphereSounds to the Sphere1 and Sphere2 objects in the Hierarchy.
  • 在 Visual Studio 中打开SphereSounds , 更新以下代码并全部保存Open SphereSounds in Visual Studio, update the following code and Save All.
using UnityEngine;

public class SphereSounds : MonoBehaviour
{
    AudioSource impactAudioSource = null;
    AudioSource rollingAudioSource = null;

    bool rolling = false;

    void Start()
    {
        // Add an AudioSource component and set up some defaults
        impactAudioSource = gameObject.AddComponent<AudioSource>();
        impactAudioSource.playOnAwake = false;
        impactAudioSource.spatialize = true;
        impactAudioSource.spatialBlend = 1.0f;
        impactAudioSource.dopplerLevel = 0.0f;
        impactAudioSource.rolloffMode = AudioRolloffMode.Logarithmic;
        impactAudioSource.maxDistance = 20f;

        rollingAudioSource = gameObject.AddComponent<AudioSource>();
        rollingAudioSource.playOnAwake = false;
        rollingAudioSource.spatialize = true;
        rollingAudioSource.spatialBlend = 1.0f;
        rollingAudioSource.dopplerLevel = 0.0f;
        rollingAudioSource.rolloffMode = AudioRolloffMode.Logarithmic;
        rollingAudioSource.maxDistance = 20f;
        rollingAudioSource.loop = true;

        // Load the Sphere sounds from the Resources folder
        impactAudioSource.clip = Resources.Load<AudioClip>("Impact");
        rollingAudioSource.clip = Resources.Load<AudioClip>("Rolling");
    }

    // Occurs when this object starts colliding with another object
    void OnCollisionEnter(Collision collision)
    {
        // Play an impact sound if the sphere impacts strongly enough.
        if (collision.relativeVelocity.magnitude >= 0.1f)
        {
            impactAudioSource.Play();
        }
    }

    // Occurs each frame that this object continues to collide with another object
    void OnCollisionStay(Collision collision)
    {
        Rigidbody rigid = gameObject.GetComponent<Rigidbody>();

        // Play a rolling sound if the sphere is rolling fast enough.
        if (!rolling && rigid.velocity.magnitude >= 0.01f)
        {
            rolling = true;
            rollingAudioSource.Play();
        }
        // Stop the rolling sound if rolling slows down.
        else if (rolling && rigid.velocity.magnitude < 0.01f)
        {
            rolling = false;
            rollingAudioSource.Stop();
        }
    }

    // Occurs when this object stops colliding with another object
    void OnCollisionExit(Collision collision)
    {
        // Stop the rolling sound if the object falls off and stops colliding.
        if (rolling)
        {
            rolling = false;
            impactAudioSource.Stop();
            rollingAudioSource.Stop();
        }
    }
}
  • 保存该脚本并返回到 Unity。Save the script, and return to Unity.
  • 导出应用, 生成应用并将其部署到 HoloLens。Export, build and deploy the app to your HoloLens.
  • 从舞台更近和更密切地移动, 并翻到一边, 倾听声音发生变化。Move closer and further from the Stage and turn side-to-side to hear the sounds change.

第6章-空间映射Chapter 6 - Spatial mapping

现在, 我们将使用空间映射将游戏板置于真实世界的真实对象上。Now we are going to use spatial mapping to place the game board on a real object in the real world.

目标Objectives

  • 将你的真实世界带入虚拟世界。Bring your real world into the virtual world.
  • 将全息影像置于最重要的位置。Place your holograms where they matter most to you.

说明Instructions

  • 在 Unity 中, 在 "项目" 面板中单击 "全息影像" 文件夹。In Unity, click on the Holograms folder in the Project panel.
  • 空间映射资产拖到层次结构的根。Drag the Spatial Mapping asset into the root of the Hierarchy.
  • 单击层次结构中的空间映射对象。Click on the Spatial Mapping object in the Hierarchy.
  • 在 "检查器" 面板中, 更改以下属性:In the Inspector panel, change the following properties:
    • 选中 "绘制可视网格" 框。Check the Draw Visual Meshes box.
    • 定位绘图材料, 并单击右侧的圆圈。Locate Draw Material and click the circle on the right. 在顶部的搜索字段中键入 "线框"。Type "wireframe" into the search field at the top. 单击结果, 然后关闭窗口。Click on the result and then close the window. 执行此操作时, 绘制材料的值应设置为线框。When you do this, the value for Draw Material should get set to Wireframe.
  • 导出应用, 生成应用并将其部署到 HoloLens。Export, build and deploy the app to your HoloLens.
  • 当应用程序运行时, 线框网格将覆盖你的真实世界。When the app runs, a wireframe mesh will overlay your real world.
  • 观看某个滚动球如何偏离舞台, 并观看地面!Watch how a rolling sphere will fall off the stage, and onto the floor!

现在, 我们将向你展示如何将 OrigamiCollection 移动到一个新位置:Now we'll show you how to move the OrigamiCollection to a new location:

  • 在 "脚本" 文件夹中, 创建一个名为TapToPlaceParent的脚本。In the Scripts folder, create a script named TapToPlaceParent.
  • 层次结构中, 展开 " OrigamiCollection ", 然后选择 "暂存" 对象。In the Hierarchy, expand the OrigamiCollection and select the Stage object.
  • TapToPlaceParent脚本拖到 "暂存" 对象上。Drag the TapToPlaceParent script onto the Stage object.
  • 在 Visual Studio 中打开TapToPlaceParent脚本, 并将其更新为以下内容:Open the TapToPlaceParent script in Visual Studio, and update it to be the following:
using UnityEngine;

public class TapToPlaceParent : MonoBehaviour
{
    bool placing = false;

    // Called by GazeGestureManager when the user performs a Select gesture
    void 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 frame
    void 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;
            }
        }
    }
}
  • 导出、生成并部署应用。Export, build and deploy the app.
  • 现在, 您应该能够通过 gazing 将游戏置于特定位置, 使用 "选择手势", 然后移动到一个新位置, 然后再次使用 "选择手势"。Now you should now be able to place the game in a specific location by gazing at it, using the Select gesture and then moving to a new location, and using the Select gesture again.

第7章-全息娱乐Chapter 7 - Holographic fun

目标Objectives

  • 显示全息 underworld 的入口。Reveal the entrance to a holographic underworld.

说明Instructions

接下来, 我们将向您展示如何发现全息 underworld:Now we'll show you how to uncover the holographic underworld:

  • 从 "项目" 面板中的 "全息影像" 文件夹:From the Holograms folder in the Project Panel:
    • Underworld拖到层次结构中, 使其成为OrigamiCollection的子元素。Drag Underworld into the Hierarchy to be a child of OrigamiCollection.
  • 在 "脚本" 文件夹中, 创建一个名为HitTarget的脚本。In the Scripts folder, create a script named HitTarget.
  • 层次结构中, 展开 " OrigamiCollection"。In the Hierarchy, expand the OrigamiCollection.
  • 展开 "暂存" 对象并选择目标对象 (蓝色风扇)。Expand the Stage object and select the Target object (blue fan).
  • HitTarget脚本拖到目标对象上。Drag the HitTarget script onto the Target object.
  • 在 Visual Studio 中打开HitTarget脚本, 并将其更新为以下内容:Open the HitTarget script in Visual Studio, and update it to be the following:
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 object
    void 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 中, 选择目标对象。In Unity, select the Target object.
  • 现在, 两个公共属性在命中目标组件上可见, 需要引用场景中的对象:Two public properties are now visible on the Hit Target component and need to reference objects in our scene:
    • Underworld从 "层次结构" 面板拖到命中目标组件上的 " Underworld " 属性。Drag Underworld from the Hierarchy panel to the Underworld property on the Hit Target component.
    • 从 "层次结构" 面板将 "阶段" 拖到对象上,以隐藏 命中目标组件的属性。Drag Stage from the Hierarchy panel to the Object to Hide property on the Hit Target component.
  • 导出、生成并部署应用。Export, build and deploy the app.
  • 将日式折纸收集到地面上, 然后使用 "选择手势" 创建球体放置。Place the Origami Collection on the floor, and then use the Select gesture to make a sphere drop.
  • 当球到达目标 (蓝色风扇) 时, 将发生爆炸。When the sphere hits the target (blue fan), an explosion will occur. 该集合将隐藏, 并且将显示 underworld 的孔。The collection will be hidden and a hole to the underworld will appear.

结束The end

这就是本教程的结尾!And that's the end of this tutorial!

已学习:You learned:

  • 如何在 Unity 中创建全息应用。How to create a holographic app in Unity.
  • 如何使用注视、手势、语音、声音和空间映射。How to make use of gaze, gesture, voice, sound, and spatial mapping.
  • 如何使用 Visual Studio 生成和部署应用。How to build and deploy an app using Visual Studio.

你现在已准备好开始创建自己的全息体验!You are now ready to start creating your own holographic experience!

请参阅See also