MR 基础知识 101:使用设备设置完整的项目MR Basics 101: Complete project with device


备注

混合现实学院教程在制作时考虑到了 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 发布了一系列新教程A new series of tutorials has been posted for HoloLens 2.


本教程将引导你完成 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.

InstructionsInstructions

  • 启动 Unity。Start Unity.
  • 选择“打开” 。Select Open.
  • 输入 "位置" 作为以前未存档的 日式折纸 文件夹。Enter location as the Origami folder you previously un-archived.
  • 选择 " 日式折纸 " 并单击 " 选择文件夹"。Select Origami and click Select Folder.
  • 由于 日式折纸 项目不包含场景,因此请将空的默认场景保存到新文件,使用: file / save 场景 AsSince 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”设置为“0” 。Set 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.

InstructionsInstructions

  • 返回到 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.

InstructionsInstructions

首先,我们将创建一个脚本,然后可以检测选择的手势。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.

InstructionsInstructions

  • 在 " 脚本 " 文件夹中,创建一个名为 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.

InstructionsInstructions

  • 在 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.

InstructionsInstructions

  • 在 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.

InstructionsInstructions

接下来,我们将向您展示如何发现全息 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