这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/holograms_210

Hololens的使用如果类比到计算机的使用,在输入操作方面,Hololens了解用户的操作意图的第一个步骤是凝视,用户的凝视射线呈现在场景中的点为凝视点,就好像是电脑中的鼠标光标点,凝视是第一步,是人与hololens操作的开始。

涉及凝视相关的知识点如下:

1 当用户看着一个全息图时,光标点会有反馈表现—表明用户看到了全息图,当用户凝视视线离开全息图时,光标点也要有反馈-表明用户没有在看全息图。

2 当用户注视到全息图时,给于用户更多反馈,例如声音,全息图当变化等。

3 使用定位技术使得用户可以选中更小的全息图。

4 添加方向指示图标指引用户找到全息图

5全息指示面板追随用户移动,一直保持在用户可见视角之内。

前提条件:

1 一台已经安装好开发工具的windows10 pc

2 一些C#编程能力

3 已经完成了教程 Holograms-101

4 一个开发者模式的Hololens 设备

项目文件:

下载该教程所需文件files

章节1-Unity 设置

步骤:

  • 开启 Unity.
  • 选择 New Project.
  • 给项目命名为 ModelExplorer.
  • 保存地址到你下载的项目文件下的 Gaze 文件夹下
  • 选择为 3D项目.
  • 点击 Create Project.

发布到Hololens设备前的一些Unity必要设置

  • 到Unity中选择 Edit > Project Settings > Player.
  • 在右侧的Inspector Panel 面板中, 选择 Windows Store 图标.
  • 展开 Other Settings 组.
  • Rendering 部分, 勾选 Virtual Reality Supported 选框 以添加一个新的 Virtual Reality SDKs 列表.
  • 验证 Windows Holographic 是否在列表中. 如果不在,选择 + 按钮将 Windows Holographic添加进列表.
  • 在主工具栏中选择Edit > Project Settings > Quality.
  • 依然是右侧的Inspector面板,在 Windows Store 图标下点击Default 下拉箭头.
  • 选择 Fastest for Windows Store Apps.

导入美术资源

  • 右击Project 面板下Assets 文件夹.
  • 点击 Import Package > Custom Package.
  • 定位到你下载的项目文件,然后选择 ModelExplorer.unitypackage.
  • 点击 Open.
  • 在出现的小窗口中,选择 Import button.

场景设置

  • 删除 Hierarchy面板中的 Main Camera.
  • 在Project面板下,找到 HoloToolkit 文件夹, 打开 Utilities folder, 然后打开 Prefabs folder.
  • 拖拽Prefabs文件夹下的 Main CameraHierarchy 面板中.
  • 右击Hierarchy中的Directional Light 然后选择 Delete.
  • 在Project面板下的 Holograms 文件夹下, 拖拽以下资源到 Hierarchy面板中:
    • AstroMan
    • Lights
    • SpaceAudioSource
    • SpaceBackground
    • Fitbox
  • 选择Hierarchy 面板下的Fitbox
  • 拖拽场景中的 AstroMan 到右侧Fitbox的Inspector 面板中的Hologram Collection 属性

发布项目

  • 保存当前场景: File > Save Scene As.
  • 点击 New Folder 命名新文件夹为 Scenes.
  • 将当前场景命名为 “ModelExplorer” 然后保存在刚新建的 Scenes 文件夹下.
  • 返回Unity,选择 File > Build Settings.
  • 点击 Add Open Scenes 添加ModelExplorer场景.
  • 选择 Windows Store然后点击Switch Platform.
  • 设置 SDKUniversal 10Build TypeD3D.
  • 勾选 Unity C# Projects.
  • 点击 Build.
  • 创建一个新的文件夹命名为  "App".
  • 单击App文件夹
  • 选择 Select Folder.
  • 当Unity Build完成后, 一个新的文件窗口会出现.
  • 打开其 App Folder.
  • 打开 ModelExplorer Visual Studio Solution.
  • 在 Visual Studio中, 右击 Package.appxmanifest 文件选择查看代码
  • 定位代码中的 TargetDeviceFamily 然后将名称改掉, Name="Windows.Universal" 变为Name="Windows.Holographic".
  • 点击保存 Package.appxmanifest.
  • 在 Visual Studio顶部工具栏中, 将 Debug 改为 Release ,将 ARM 改为 x86.
  • 点击Device 按钮的下拉箭头, 然后选择远程设备 Remote Machine.
  • 输入你设备的IP地址, 然后将认证模式设为 Universal (Unencrypted Protocol). 点击 Select. 如果你不知道你设备的IP地址, 打开你的设备,在 Settings > Network & Internet > Advanced Options中可以查看到.
  • 在VS的顶部工具栏, 点击 Debug -> Start Without debugging 或者 Ctrl + F5. 如果这是你第一次部署到你的设备, 你需要进行配对 pair it with Visual Studio.
  • 部署完成后,  可以使用选择手势关闭Fixbox.

章节2 光标点与目标反馈

光标设计遵循以下原则:

1 光标要一直出现在视角中

2 光标不能太小也不能太大

3 光标不能遮挡内容

步骤:

  • Hierarchy 面板的顶部点击Create 按钮.
  • 选择 Create Empty.
  • 点击新创建的 GameObject 然后将它名称改为为 "Managers".
  • Hierarchy 面板下, 选择 Managers 对象.
  • Inspector 面板下, 点击 Add Component 按钮.
  • 在搜索框输入 Gaze Manager. 选择此结果.
  • Inspector 面板下, 选择 RaycastLayerMask 下拉单 将勾选的 TransparentFX 去掉.
  • 在project面板下,找到HoloToolkit\Input\Prefabs 文件夹, 找到 Cursor 对象.
  • 拖拽此对象 CursorHierarchy.
  • Hierarchy 面板下, 选择Cursor 对象.
  • Inspector 面板下, 点击Add Component 按钮.
  • 在搜索框输入Cursor Manager. 选择此结果.
  • 展开Hierarchy 面板下的Cursor 对象.
  • 拖拽 CursorOnHolograms 对象到右侧Inspector 面板下的Cursor On Holograms 属性中。
  • 同理拖拽 CursorOffHolograms 对象到右侧Inspector 面板下的  Cursor Off Holograms 属性中。

接下来你需要编辑GazeManager.cs 代码,实现以下几点:

1 执行一个物理射线physics raycast,

2 存储射线交叉点的位置和法线position and normal

3 如果射线没有击中任何对象,将位置与法线设为默认值

GazeManager.cs

using HoloToolkit;
using UnityEngine; /// <summary>
/// GazeManager determines the location of the user's gaze, hit position and normals.
/// </summary>
public class GazeManager : Singleton<GazeManager>
{
[Tooltip("Maximum gaze distance for calculating a hit.")]
public float MaxGazeDistance = 5.0f; [Tooltip("Select the layers raycast should target.")]
public LayerMask RaycastLayerMask = Physics.DefaultRaycastLayers; /// <summary>
/// Physics.Raycast result is true if it hits a Hologram.
/// </summary>
public bool Hit { get; private set; } /// <summary>
/// HitInfo property gives access
/// to RaycastHit public members.
/// </summary>
public RaycastHit HitInfo { get; private set; } /// <summary>
/// Position of the user's gaze.
/// </summary>
public Vector3 Position { get; private set; } /// <summary>
/// RaycastHit Normal direction.
/// </summary>
public Vector3 Normal { get; private set; } private GazeStabilizer gazeStabilizer;
private Vector3 gazeOrigin;
private Vector3 gazeDirection; void Awake()
{
/* TODO: DEVELOPER CODING EXERCISE 3.a */ // 3.a: GetComponent GazeStabilizer and assign it to gazeStabilizer. } private void Update()
{
// 2.a: Assign Camera's main transform position to gazeOrigin.
gazeOrigin = Camera.main.transform.position; // 2.a: Assign Camera's main transform forward to gazeDirection.
gazeDirection = Camera.main.transform.forward; // 3.a: Using gazeStabilizer, call function UpdateHeadStability.
// Pass in gazeOrigin and Camera's main transform rotation. // 3.a: Using gazeStabilizer, get the StableHeadPosition and
// assign it to gazeOrigin. UpdateRaycast();
} /// <summary>
/// Calculates the Raycast hit position and normal.
/// </summary>
private void UpdateRaycast()
{
/* TODO: DEVELOPER CODING EXERCISE 2.a */ // 2.a: Create a variable hitInfo of type RaycastHit.
RaycastHit hitInfo; // 2.a: Perform a Unity Physics Raycast.
// Collect return value in public property Hit.
// Pass in origin as gazeOrigin and direction as gazeDirection.
// Collect the information in hitInfo.
// Pass in MaxGazeDistance and RaycastLayerMask.
Hit = Physics.Raycast(gazeOrigin,
gazeDirection,
out hitInfo,
MaxGazeDistance,
RaycastLayerMask); // 2.a: Assign hitInfo variable to the HitInfo public property
// so other classes can access it.
HitInfo = hitInfo; if (Hit)
{
// If raycast hit a hologram... // 2.a: Assign property Position to be the hitInfo point.
Position = hitInfo.point;
// 2.a: Assign property Normal to be the hitInfo normal.
Normal = hitInfo.normal;
}
else
{
// If raycast did not hit a hologram... // Save defaults ... // 2.a: Assign Position to be gazeOrigin plus MaxGazeDistance times gazeDirection.
Position = gazeOrigin + (gazeDirection * MaxGazeDistance);
// 2.a: Assign Normal to be the user's gazeDirection.
Normal = gazeDirection;
}
}
}

GazeManager

接下来你要编辑 CusorManager.cs 代码实现以下目标:

1 判断哪个光标状态应该被激活,
2 根据光标是否在全息图上来不断更新光标状态
3 始终将光标放在用户正在注视的位置。

CursorManager.cs

using HoloToolkit;
using UnityEngine; /// <summary>
/// CursorManager class takes Cursor GameObjects.
/// One that is on Holograms and another off Holograms.
/// Shows the appropriate Cursor when a Hologram is hit.
/// Places the appropriate Cursor at the hit position.
/// Matches the Cursor normal to the hit surface.
/// </summary>
public class CursorManager : Singleton<CursorManager>
{
[Tooltip("Drag the Cursor object to show when it hits a hologram.")]
public GameObject CursorOnHolograms; [Tooltip("Drag the Cursor object to show when it does not hit a hologram.")]
public GameObject CursorOffHolograms; void Awake()
{
if (CursorOnHolograms == null || CursorOffHolograms == null)
{
return;
} // Hide the Cursors to begin with.
CursorOnHolograms.SetActive(false);
CursorOffHolograms.SetActive(false);
} void Update()
{
/* TODO: DEVELOPER CODING EXERCISE 2.b */ if (GazeManager.Instance == null || CursorOnHolograms == null || CursorOffHolograms == null)
{
return;
} if (GazeManager.Instance.Hit)
{
// 2.b: SetActive true the CursorOnHolograms to show cursor.
CursorOnHolograms.SetActive(true);
// 2.b: SetActive false the CursorOffHolograms hide cursor.
CursorOffHolograms.SetActive(false);
}
else
{
// 2.b: SetActive true CursorOffHolograms to show cursor.
CursorOffHolograms.SetActive(true);
// 2.b: SetActive false CursorOnHolograms to hide cursor.
CursorOnHolograms.SetActive(false);
} // 2.b: Assign gameObject's transform position equals GazeManager's instance Position.
gameObject.transform.position = GazeManager.Instance.Position; // 2.b: Assign gameObject's transform up vector equals GazeManager's instance Normal.
gameObject.transform.up = GazeManager.Instance.Normal;
}
}

CursorManager

接下来可以再次发布部署一次APP,看一下当光标移动到全息图上时光标的变化。

全息图的凝视反馈:

步骤:

  • Hierarchy 面板中, 选择 Managers 对象.
  • 在右侧 Inspector 面板中, 点击 Add Component 按钮.
  • 在搜索框中输入 Interactible Manager. 选择此结果.
  • Hierarchy 面板中, 选择AstroMan 对象.
  • 在右侧 Inspector 面板中, 点击 Add Component 按钮.
  • 在搜索框中输入 Interactible . 选择此结果.

接下来你需要编辑 InteractibleManager.csInteractible.cs 两个代码文件来实现以下功能 :

  1. InteractibleManager.cs 脚本中,获取凝视射线击中的点和保存碰撞对象 collided GameObject.
  2. 当凝视交点在你可以交互的全息对象上时发送 GazeEntered message
  3. 当凝视交点离开你可以交互的全息对象上时发送 GazeExited message
  4. 在Interactible.cs 代码中处理GazeEntered和GazeExited回调。
using HoloToolkit;
using UnityEngine; /// <summary>
/// InteractibleManager keeps tracks of which GameObject
/// is currently in focus.
/// </summary>
public class InteractibleManager : Singleton<InteractibleManager>
{
public GameObject FocusedGameObject { get; private set; } private GameObject oldFocusedGameObject = null; void Start()
{
FocusedGameObject = null;
} void Update()
{
/* TODO: DEVELOPER CODING EXERCISE 2.c */ oldFocusedGameObject = FocusedGameObject; if (GazeManager.Instance.Hit)
{
RaycastHit hitInfo = GazeManager.Instance.HitInfo;
if (hitInfo.collider != null)
{
// 2.c: Assign the hitInfo's collider gameObject to the FocusedGameObject.
FocusedGameObject = hitInfo.collider.gameObject;
}
else
{
FocusedGameObject = null;
}
}
else
{
FocusedGameObject = null;
} if (FocusedGameObject != oldFocusedGameObject)
{
ResetFocusedInteractible(); if (FocusedGameObject != null)
{
if (FocusedGameObject.GetComponent<Interactible>() != null)
{
// 2.c: Send a GazeEntered message to the FocusedGameObject.
FocusedGameObject.SendMessage("GazeEntered");
}
}
}
} private void ResetFocusedInteractible()
{
if (oldFocusedGameObject != null)
{
if (oldFocusedGameObject.GetComponent<Interactible>() != null)
{
// 2.c: Send a GazeExited message to the oldFocusedGameObject.
oldFocusedGameObject.SendMessage("GazeExited");
}
}
}
}

InteractibleManager

using UnityEngine;

/// <summary>
/// The Interactible class flags a Game Object as being "Interactible".
/// Determines what happens when an Interactible is being gazed at.
/// </summary>
public class Interactible : MonoBehaviour
{
[Tooltip("Audio clip to play when interacting with this hologram.")]
public AudioClip TargetFeedbackSound;
private AudioSource audioSource; private Material[] defaultMaterials; void Start()
{
defaultMaterials = GetComponent<Renderer>().materials; // Add a BoxCollider if the interactible does not contain one.
Collider collider = GetComponentInChildren<Collider>();
if (collider == null)
{
gameObject.AddComponent<BoxCollider>();
} EnableAudioHapticFeedback();
} private void EnableAudioHapticFeedback()
{
// If this hologram has an audio clip, add an AudioSource with this clip.
if (TargetFeedbackSound != null)
{
audioSource = GetComponent<AudioSource>();
if (audioSource == null)
{
audioSource = gameObject.AddComponent<AudioSource>();
} audioSource.clip = TargetFeedbackSound;
audioSource.playOnAwake = false;
audioSource.spatialBlend = ;
audioSource.dopplerLevel = ;
}
} /* TODO: DEVELOPER CODING EXERCISE 2.d */ void GazeEntered()
{
for (int i = ; i < defaultMaterials.Length; i++)
{
// 2.d: Uncomment the below line to highlight the material when gaze enters.
defaultMaterials[i].SetFloat("_Highlight", .25f);
}
} void GazeExited()
{
for (int i = ; i < defaultMaterials.Length; i++)
{
// 2.d: Uncomment the below line to remove highlight on material when gaze exits.
defaultMaterials[i].SetFloat("_Highlight", 0f);
}
} void OnSelect()
{
for (int i = ; i < defaultMaterials.Length; i++)
{
defaultMaterials[i].SetFloat("_Highlight", .5f);
} // Play the audioSource feedback when we gaze and select a hologram.
if (audioSource != null && !audioSource.isPlaying)
{
audioSource.Play();
} /* TODO: DEVELOPER CODING EXERCISE 6.a */
// 6.a: Handle the OnSelect by sending a PerformTagAlong message. }
}

Interactible

接下来你可以再一次发布部署到Hololens上查看当凝视点击中全息图时,全息图的反馈状态。

章节3 定位技术

目标:更容易定位到全息对象,稳定且自然到头部移动

步骤:

  1. Hierarchy 面板中, 选择 Managers 对象.
  2. 在右侧 Inspector 面板中, 点击 Add Component 按钮.
  3. 在搜索框中输入 Gaze Stabilizer. 选择此结果.

接下来需要更新GazeManager 脚本

  1. 用VS打开GazeManager脚本 .
  2. 粘贴以下代码到GazeManager.cs
using HoloToolkit;
using UnityEngine; /// <summary>
/// GazeManager determines the location of the user's gaze, hit position and normals.
/// </summary>
public class GazeManager : Singleton<GazeManager>
{
[Tooltip("Maximum gaze distance for calculating a hit.")]
public float MaxGazeDistance = 5.0f; [Tooltip("Select the layers raycast should target.")]
public LayerMask RaycastLayerMask = Physics.DefaultRaycastLayers; /// <summary>
/// Physics.Raycast result is true if it hits a Hologram.
/// </summary>
public bool Hit { get; private set; } /// <summary>
/// HitInfo property gives access
/// to RaycastHit public members.
/// </summary>
public RaycastHit HitInfo { get; private set; } /// <summary>
/// Position of the user's gaze.
/// </summary>
public Vector3 Position { get; private set; } /// <summary>
/// RaycastHit Normal direction.
/// </summary>
public Vector3 Normal { get; private set; } private GazeStabilizer gazeStabilizer;
private Vector3 gazeOrigin;
private Vector3 gazeDirection; void Awake()
{
/* TODO: DEVELOPER CODING EXERCISE 3.a */ // 3.a: GetComponent GazeStabilizer and assign it to gazeStabilizer.
gazeStabilizer = GetComponent<GazeStabilizer>();
} private void Update()
{
// 2.a: Assign Camera's main transform position to gazeOrigin.
gazeOrigin = Camera.main.transform.position; // 2.a: Assign Camera's main transform forward to gazeDirection.
gazeDirection = Camera.main.transform.forward; // 3.a: Using gazeStabilizer, call function UpdateHeadStability.
// Pass in gazeOrigin and Camera's main transform rotation.
gazeStabilizer.UpdateHeadStability(gazeOrigin, Camera.main.transform.rotation); // 3.a: Using gazeStabilizer, get the StableHeadPosition and
// assign it to gazeOrigin.
gazeOrigin = gazeStabilizer.StableHeadPosition; UpdateRaycast();
} /// <summary>
/// Calculates the Raycast hit position and normal.
/// </summary>
private void UpdateRaycast()
{
/* TODO: DEVELOPER CODING EXERCISE 2.a */ // 2.a: Create a variable hitInfo of type RaycastHit.
RaycastHit hitInfo; // 2.a: Perform a Unity Physics Raycast.
// Collect return value in public property Hit.
// Pass in origin as gazeOrigin and direction as gazeDirection.
// Collect the information in hitInfo.
// Pass in MaxGazeDistance and RaycastLayerMask.
Hit = Physics.Raycast(gazeOrigin,
gazeDirection,
out hitInfo,
MaxGazeDistance,
RaycastLayerMask); // 2.a: Assign hitInfo variable to the HitInfo public property
// so other classes can access it.
HitInfo = hitInfo; if (Hit)
{
// If raycast hit a hologram... // 2.a: Assign property Position to be the hitInfo point.
Position = hitInfo.point;
// 2.a: Assign property Normal to be the hitInfo normal.
Normal = hitInfo.normal;
}
else
{
// If raycast did not hit a hologram...
// Save defaults ... // 2.a: Assign Position to be gazeOrigin plus MaxGazeDistance times gazeDirection.
Position = gazeOrigin + (gazeDirection * MaxGazeDistance);
// 2.a: Assign Normal to be the user's gazeDirection.
Normal = gazeDirection;
}
}
}

GazeManager

章节4 方向指示器

给光标添加一个方向箭头使得用户更容易找到全息对象。

步骤:

  • 点击Hierarchy 面板下的AstroMan 对象然后点击小箭头展开它
  • 选中AstroMan下的DirectionalIndicator.
  • 在右侧的 Inspector面板中点击Add Component 按钮.
  • 在搜索框输入Direction Indicator. 选择此结果.
  • 此时拖拽Hierarchy面板下的Cursor 对象 到右侧Inspector面板下Cursor属性中.
  • Project 面板下, 拖拽 Holograms 文件夹下的 DirectionalIndicator 资源到右侧Inspector中的Directional Indicator 属性里
  • 部署发布项目
  • 看方向指示器如何帮助你找到宇航员

章节5 广告牌

我们使用一个广告牌来使得全息对象始终面向用户

  • Hierarchy 面板中, 选择 AstroMan 对象.
  • 在右侧的 Inspector面板中点击Add Component 按钮.
  • 在搜索框输入Billboard. 选择此结果.
  • Inspector面板中Pivot Axis属性设置为Y.
  • 现在可以发布到Hololens上看看效果
  • 看看全息图是不是一直都面向你,无论你怎么转换视角

在做接下来的教程时先把 AstroMan 中的Billboard 脚本删掉

章节6 追随标签

使用追随标签可以使得我们的全息对象追随我们到房间的任何位置。

追随全息对象的设计应遵循以下原则:

1 全息内容应该在视角范围内一眼就可以看到

2全息内容不能显示在用户前进路上

3 头部锁定内容是不舒服的

我们可以想象这个Tag-along全息对象一直保持在我们视角的边缘,无论我们走到哪里,我们都可以一眼就看到它。

步骤:

  1. Hierarchy 面板中, 选择 Managers 对象.
  2. 在右侧 Inspector 面板中, 点击 Add Component 按钮.
  3. 在搜索框中输入  Gesture Manager. 选择此结果.

接下来将使用SimpleTagalong.cs 文件,它会做到:

  1. 确定 Tag-Along 对象是否在摄像机边界内.
  2. 如果不在视椎体内, 定位 Tag-Along 对象部分到摄像机到视椎体内.
  3. 否则, 定位 Tag-Along 对象到离用户固定距离的位置上。

接下来要做:

  • Holograms 文件夹下找到 Tagalong asset并点击.
  • 在右侧 Inspector面板中,  上方有个Tag 下拉列表,点击 Add Tag ….
  • 点击+ ,然后将 Tag 0 命名为 TagAlong.
  • Holograms 文件夹下点击 Tagalong asset然后点击右侧Inspector面板中Tag dropdown.
  • 选择 TagAlong 标签.
  • 我们必须编辑 Interactible.cs 脚本 发送信息到 InteractibleAction.
using UnityEngine;

/// <summary>
/// The Interactible class flags a Game Object as being "Interactible".
/// Determines what happens when an Interactible is being gazed at.
/// </summary>
public class Interactible : MonoBehaviour
{
[Tooltip("Audio clip to play when interacting with this hologram.")]
public AudioClip TargetFeedbackSound;
private AudioSource audioSource; private Material[] defaultMaterials; void Start()
{
defaultMaterials = GetComponent<Renderer>().materials; // Add a BoxCollider if the interactible does not contain one.
Collider collider = GetComponentInChildren<Collider>();
if (collider == null)
{
gameObject.AddComponent<BoxCollider>();
} EnableAudioHapticFeedback();
} private void EnableAudioHapticFeedback()
{
// If this hologram has an audio clip, add an AudioSource with this clip.
if (TargetFeedbackSound != null)
{
audioSource = GetComponent<AudioSource>();
if (audioSource == null)
{
audioSource = gameObject.AddComponent<AudioSource>();
} audioSource.clip = TargetFeedbackSound;
audioSource.playOnAwake = false;
audioSource.spatialBlend = ;
audioSource.dopplerLevel = ;
}
} /* TODO: DEVELOPER CODING EXERCISE 2.d */ void GazeEntered()
{
for (int i = ; i < defaultMaterials.Length; i++)
{
// 2.d: Uncomment the below line to highlight the material when gaze enters.
defaultMaterials[i].SetFloat("_Highlight", .25f);
}
} void GazeExited()
{
for (int i = ; i < defaultMaterials.Length; i++)
{
// 2.d: Uncomment the below line to remove highlight on material when gaze exits.
defaultMaterials[i].SetFloat("_Highlight", 0f);
}
} void OnSelect()
{
for (int i = ; i < defaultMaterials.Length; i++)
{
defaultMaterials[i].SetFloat("_Highlight", .5f);
} // Play the audioSource feedback when we gaze and select a hologram.
if (audioSource != null && !audioSource.isPlaying)
{
audioSource.Play();
} /* TODO: DEVELOPER CODING EXERCISE 6.a */
// 6.a: Handle the OnSelect by sending a PerformTagAlong message.
SendMessage("PerformTagAlong");
}
}

Interactible

InteractibleAction.cs脚本在您注视全息图时执行自定义操作。 让我们更新它与标签一起使用。

  • Complete the coding exercise or change it to this:

    • Hierarchy 面板的顶部的搜索框内输入ChestButton_Center 然后选择它.
    • 在右侧Inspector 面板下点击 Add Component 按钮.
    • 在搜索框内输入 Interactible Action. 并选择
    • 在project面板下 Holograms 文件夹中找到 Tagalong asset.
    • 选中Hierarchy面板下的 ChestButton_Center 对象. 拖拽 TagAlong 对象从 Project 面板到右侧 Inspector 面板中到 Object to TagAlong property.
    • Double click the InteractibleAction script to open it in Visual Studio.
using HoloToolkit;
using UnityEngine; /// <summary>
/// InteractibleAction performs custom actions when you gaze at the holograms.
/// </summary>
public class InteractibleAction : MonoBehaviour
{
[Tooltip("Drag the Tagalong prefab asset you want to display.")]
public GameObject ObjectToTagAlong; void PerformTagAlong()
{
if (ObjectToTagAlong == null)
{
return;
} // Recommend having only one tagalong.
GameObject existingTagAlong = GameObject.FindGameObjectWithTag("TagAlong");
if (existingTagAlong != null)
{
return;
} GameObject instantiatedObjectToTagAlong = GameObject.Instantiate(ObjectToTagAlong); instantiatedObjectToTagAlong.SetActive(true); /* TODO: DEVELOPER CODING EXERCISE 6.b */ // 6.b: AddComponent Billboard to instantiatedObjectToTagAlong.
// So it's always facing the user as they move.
instantiatedObjectToTagAlong.AddComponent<Billboard>(); // 6.b: AddComponent SimpleTagalong to instantiatedObjectToTagAlong.
// So it's always following the user as they move.
instantiatedObjectToTagAlong.AddComponent<SimpleTagalong>(); // 6.b: Set any public properties you wish to experiment with.
}
}

InteractibleAction

发布部署到设备上查看

原文链接https://developer.microsoft.com/en-us/windows/holographic/holograms_210

如有翻译上的错误请指正。谢谢

微软Hololens学院教程-Hologram 210 Gaze(凝视)【微软教程已经更新,本文是老版本】的更多相关文章

  1. 微软Hololens学院教程-Hologram 230-空间场景建模(Spatial mapping )【微软教程已经更新,本文是老版本】

    这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/ho ...

  2. 微软Hololens学院教程-Hologram 211-Gestures(手势)【微软教程已经更新,本文是老版本】

    这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/ho ...

  3. 微软Hololens学院教程-Hologram 212-Voice(语音)【微软教程已经更新,本文是老版本】

    这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/ho ...

  4. 微软Hololens学院教程-Hologram 220-空间声音(Spatial sound )【本文是老版本,与最新的微软教程有出入】

    这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦! 原文链接https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/ho ...

  5. 微软Hololens学院教程- Holograms 101: Introduction with Device【微软教程已经更新,本文是老版本】

    这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/ho ...

  6. 微软Hololens学院教程- Holograms 100: Getting Started with Unity【微软教程已经更新,本文是老版本】

    这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/ho ...

  7. HoloLens开发手记 - Unity之Gaze凝视射线

    凝视是HoloLens首要输入方式,形式功能类似于桌面系统的光标,用于选择操作全息对象.然而在Unity中并没有明确的Gaze API或者组件. 实现Gaze Implementing Gaze 概念 ...

  8. Microsoft HoloLens 开发(3): 全息图交互方式 - Gaze

    Gaze(凝视) 是 HoloLens 交互输入的第一种形式,告诉你 用户 在世界上的位置,并让你确定他们的意图. 1.Gaze的用途 作为一个 Mixed Reality 开发者,Gaze 可以做很 ...

  9. 微软Hololens设备 浅分析

    微软Hololens的定位是一款MR 设备(Mixed reality).MR与AR的不同我认为是MR能够将真实环境的场景信息与虚拟对象进行完美的融合,它是基于SLAM(SimultaneousLoc ...

随机推荐

  1. Swift超详细的基础语法-结构体,结构体构造器,定义成员方法, 值类型, 扩充函数

    知识点 基本概念 结构体的基本使用 结构体构造器(构造函数/构造方法) 结构体扩充函数(方法), 又称成员方法 结构体是值类型 1. 基本概念 1.1 概念介绍 结构体(struct)是由一系列具有相 ...

  2. Java内存溢出示例

    按照java内存的结构,发生内存溢出的地方常在于堆.栈.方法区.直接内存. 一.堆溢出 堆溢出原因莫过于对象太多导致,看代码: /** * java 堆溢出 * VM Args:-Xms20m -Xm ...

  3. pat 1006 Sign In and Sign Out (25)

    At the beginning of every day, the first person who signs in the computer room will unlock the door, ...

  4. hdu 1096 A+B for Input-Output Practice (VIII)

    A+B for Input-Output Practice (VIII) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3 ...

  5. php 首页定时生成静态页面

    往往首页的js,商务通代码加的太多,导致页面访问速度变慢,可以把首页有动态变为静态进行访问,访问速度会有所提升,不过如果更新首页数据,并不能及时更新,而是你规定的时间内固定更新一次 代码如下: < ...

  6. 20160526-20160531mybatis入门进阶

    mybatis第二天  高级映射 查询缓存 和spring整合 课程复习: mybatis是什么? mybatis是一人持久层框架,mybatis是一个不完全的ORM框架.sql语句需要程序员自己去编 ...

  7. 修改arcgis server默认js和css连接地址

    当使用ArcGIS Server 10.1发布了一个地图服务之后,在ArcGIS Server 10.1的机器上使用浏览器进入http://localhost:6080/arcgis/rest/ser ...

  8. vim自动补全:go

    1 环境配置 export GOPATH=/home/go 2 在新建GOPATH下新建三个目录 mkdir src pkg bin src 存放源码pkg 存放编译生成的文件bin 存放生成的可执行 ...

  9. Golang,用map写个单词统计器

    Golang中也有实用的泛型编程模板.如map.据Go官方团队称,其实现为Hash表,而非类似cpp或Java的红黑树.所以理论上速度更能快上几个等级(Hash与红黑树的效率对比可以看我的文章C++中 ...

  10. c# DataTable 中 Select 和 Clone 用法结合

    C# DataTable是存放数据的一个离线数据库,将数据一下加载到内存. DataTable.Select ()方法: Select();//全部查出来    Select(过滤条件);//根据过滤 ...