hololens开发教程_hololens属于什么技术[通俗易懂]

hololens开发教程_hololens属于什么技术[通俗易懂]本文首发于“洪流学堂”公众号

本文首发于“洪流学堂”公众号。
洪流学堂,让你快人几步
本教程基于Unity2017.2及Visual Studio 2017
本教程编写时间:2017年12月4日

本文内容提要

学习简单的凝视(Gaze)、手势(Guesture)、英文语音控制(Voice)、立体音效(Spatial sound)、空间映射(Spatial mapping)
将这些功能整合开发一个小应用

视频教程

本教程入门篇的视频课程也已经上线
看视频教程,细节无遗漏哦~
https://edu.csdn.net/course/detail/6639

资源下载

本文使用了官方教程的资源
原地址
如果下载有困难,百度云地址

创建工程

  1. 将下载的资源解压
  2. 打开Unity3d,按下图打开工程
    hololens开发教程_hololens属于什么技术[通俗易懂]
  3. 设置摄像机
    • 位置设置为0,0,0
    • Clear Flags设置为Solid Color
    • Background设置为0,0,0,0
      hololens开发教程_hololens属于什么技术[通俗易懂]
  4. 建立场景内容
    • 创建一个空物体,命名为OrigamiCollection
    • 将Project面板里的Holograms文件夹中的Sphere1、Sphere2、Stage拖到OrigamiCollection下面
    • 将命名为OrigamiCollection的位置设置为0,-0.5,2
    • 将Hierarchy中的Directionnal Light删掉,将Holograms文件夹中的Lights拖到Hierarchy面板中的空白处
      操作过程如本图所示
      Game视图看到的内容如下图所示:
      hololens开发教程_hololens属于什么技术[通俗易懂]
      5.保存场景
    • 按下Ctrl+S保存场景,将场景保存到Scenes/Main.unity
      hololens开发教程_hololens属于什么技术[通俗易懂]
  5. 发布测试
    • File > Build Settings,选择Universal Windows Platform,点击Switch Platform按钮
    • Target device设置为Hololens,选中Unity C# Projects
      hololens开发教程_hololens属于什么技术[通俗易懂]
    • 点击左下角Player Settings按钮,切换到Windows图标的标签页,在Capabilities中选中Microphone和SpatialPerception(本工程已经为选中状态,但是自己开发时一定要注意手动勾选,否侧会有权限问题)
      hololens开发教程_hololens属于什么技术[通俗易懂]
    • 在Build Settings面板,点击Build,在Origami文件夹下新建App文件夹并选择该文件夹
    • Build完成后,打开App文件夹下的Origami.sln,将Debug改为Release,ARM改为x86,并选中Hololens Emulator
      hololens开发教程_hololens属于什么技术[通俗易懂]
    • 点击调试 > 开始执行(不调试)或者Ctrl+F5(注意:模拟器启动慢可能会引起部署超时,这时候不要关闭模拟器,直接再次Ctrl+F5即可)
    • 出来画面了,如下!!!(画面如果是纯黑的,是因为Hololens模拟器的镜头位置记录了历史的位置,尝试左键按下移动镜头寻找)
      hololens开发教程_hololens属于什么技术[通俗易懂]

凝视(Gaze)

  1. 将Holograms目录下的Cursor拖到Hierarchy的空白处
  2. 在Scripts目录(如果没有请新建)下,创建C#脚本并命名为WorldCursor
  3. 双击打开脚本并将以下代码粘贴覆盖
using UnityEngine;

public class WorldCursor : MonoBehaviour
{
    private MeshRenderer meshRenderer;

    void Start()
    {
        // 获取物体上的MeshRenderer组件 
        meshRenderer = this.gameObject.GetComponentInChildren<MeshRenderer>();
    }

    void Update()
    {
        // 根据用户头的位置和朝向发射射线
        var headPosition = Camera.main.transform.position;
        var gazeDirection = Camera.main.transform.forward;

        RaycastHit hitInfo;

        if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
        {
            // 如果射线碰到了hologram,显示curour模型
            meshRenderer.enabled = true;

            // 将cursor移到射线碰撞的位置
            this.transform.position = hitInfo.point;

            // 将cursor与hologram的表面平行
            this.transform.rotation = Quaternion.FromToRotation(Vector3.up, hitInfo.normal);
        }
        else
        {
            // 如果涉嫌没有检测到hologram,隐藏cursor
            meshRenderer.enabled = false;
        }
    }
}
  1. 将WorldCursor脚本拖到Cursor物体上
  2. 到这可以测试一下了!效果如下:
    hololens开发教程_hololens属于什么技术[通俗易懂]

手势(Guesture)

  1. 在Scripts文件夹中创建C#脚本,名字为GazeGestureManager
  2. 将GazeGestureManager脚本拖到OrigamiCollection物体上
  3. 打开GazeGestureManager,替换为以下代码
using UnityEngine;
using UnityEngine.XR.WSA.Input;

public class GazeGestureManager : MonoBehaviour
{
    public static GazeGestureManager Instance { get; private set; }

    // 保存当前凝视的物体
    public GameObject FocusedObject { get; private set; }

    GestureRecognizer recognizer;

    void Start()
    {
        Instance = this;

        // 用来检测Select手势
        recognizer = new GestureRecognizer();
        recognizer.Tapped += (args) =>
        {
            // 向凝视的物体和父物体发送OnSelect消息
            if (FocusedObject != null)
            {
                FocusedObject.SendMessageUpwards("OnSelect", SendMessageOptions.DontRequireReceiver);
            }
        };
        recognizer.StartCapturingGestures();
    }

    void Update()
    {
        GameObject oldFocusObject = FocusedObject;

        // 根据头的位置和方向发射射线
        var headPosition = Camera.main.transform.position;
        var gazeDirection = Camera.main.transform.forward;

        RaycastHit hitInfo;
        if (Physics.Raycast(headPosition, gazeDirection, out hitInfo))
        {
            // 如果射线检测到物体,作为凝视的物体
            FocusedObject = hitInfo.collider.gameObject;
        }
        else
        {
            // 如果射线没有检测到物体,清空FocusedObject
            FocusedObject = null;
        }

        // 如果凝视的物体发生了改变,重新开始检测手势
        if (FocusedObject != oldFocusObject)
        {
            recognizer.CancelGestures();
            recognizer.StartCapturingGestures();
        }
    }
}
  1. 在Scripts文件夹下创建SphereCommands脚本
  2. 脚本中替换以下代码
using UnityEngine;

public class SphereCommands : MonoBehaviour
{
    // 检测到Select手势时,GazeGestureManager会发送此消息
    void OnSelect()
    {
        // 如果球体没有刚体组件,添加一个,这样可以启用物理属性
        if (!this.GetComponent<Rigidbody>())
        {
            var rigidbody = this.gameObject.AddComponent<Rigidbody>();
            rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
        }
    }
}
  1. 将SphereCommands脚本拖到Sphere1和Sphere2上面
  2. 可以build测试啦!在模拟器中按空格鼠标右键模拟Select手势
    hololens开发教程_hololens属于什么技术[通俗易懂]

英文语音控制(Voice)

  1. 在Scripts文件夹中创建SpeechManager脚本,并替换为以下脚本
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", () =>
        {
            // 在每个会掉落的物体上调用OnReset方法
            this.BroadcastMessage("OnReset");
        });

        keywords.Add("Drop", () =>
        {
            var focusObject = GazeGestureManager.Instance.FocusedObject;
            if (focusObject != null)
            {
                // 在凝视的物体上调用OnDrop方法
                focusObject.SendMessage("OnDrop", SendMessageOptions.DontRequireReceiver);
            }
        });

        // 根据关键字创建KeywordRecognizer
        keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray());

        // 给KeywordRecognizer的OnPhraseRecognized注册一个回调函数
        keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;
        // 开始识别
        keywordRecognizer.Start();
    }

    private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args)
    {
        Debug.Log(args.text);
        System.Action keywordAction;
        if (keywords.TryGetValue(args.text, out keywordAction))
        {
            keywordAction.Invoke();
        }
    }
}
  1. 将SpeechManager 脚本拖到OrigamiCollection物体上
  2. 将SphereCommands 更新替换为下面的代码
using UnityEngine;

public class SphereCommands : MonoBehaviour
{
    Vector3 originalPosition;

    void Start()
    {
        // 存储球体的初始位置,用于后面重置位置
        originalPosition = this.transform.localPosition;
    }

    // 检测到Select手势时,GazeGestureManager会发送此消息
    void OnSelect()
    {
        // 如果球体没有刚体组件,添加一个,这样可以启用物理属性
        if (!this.GetComponent<Rigidbody>())
        {
            var rigidbody = this.gameObject.AddComponent<Rigidbody>();
            rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;
        }
    }

    // 当用户说“Reset world”命令时,SpeechManager会调用此方法
    void OnReset()
    {
        // 如果球体有刚体组件,移除该组件来禁用物理属性
        var rigidbody = this.GetComponent<Rigidbody>();
        if (rigidbody != null)
        {
            rigidbody.isKinematic = true;
            Destroy(rigidbody);
        }

        // 将球体的位置设置为初始的local位置
        this.transform.localPosition = originalPosition;
    }

    // 当用户说“Drop sphere”命令时,SpeechManager会调用此方法
    void OnDrop()
    {
        // 同Select的逻辑
        OnSelect();
    }
}
  1. 可以build测试啦!(注意选中Capabilities中的Microphone)
  2. 凝视一个球体,说“Drop”来使小球掉落
  3. 说“Reset”重置小球的位置

立体音效(Spatial sound)

  1. Edit > Project Settings > Audio
  2. Spatializer Plugin 选择 MS HRTF Spatializer
  3. 将Holograms文件夹下的Ambience音频拖到OrigamiCollection物体上
  4. 选中OrigamiCollection并找到Audio Source组件,修改一下内容:
    • 选中Spatialize 属性
    • 选中Play On Awake.
    • 将Spatial Blend的滑条拖到最右边(3D)
    • 选中Loop(循环)属性
    • 展开3D Sound Settings, 在Doppler Level中输入0.1
    • Volume Rolloff设置为Logarithmic Rolloff
    • Max Distance设置为20
  5. 在Scripts 文件夹中创建SphereSounds脚本,并替换为以下代码
using UnityEngine;

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

    bool rolling = false;

    void Start()
    {
        // 添加AudioSource组件并设置参数
        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;

        // 从Resources文件夹中加载声音
        impactAudioSource.clip = Resources.Load<AudioClip>("Impact");
        rollingAudioSource.clip = Resources.Load<AudioClip>("Rolling");
    }

    // 物体与其他物体碰撞时,会收到此消息
    void OnCollisionEnter(Collision collision)
    {
        // 如果碰撞够强烈,播放碰撞音效
        if (collision.relativeVelocity.magnitude >= 0.1f)
        {
            impactAudioSource.Play();
        }
    }

    // 物体与其他物体持续碰撞时,每帧都会收到此消息
    void OnCollisionStay(Collision collision)
    {
        Rigidbody rigid = gameObject.GetComponent<Rigidbody>();

        // 如果小球滚动的够快,播放滚动音效
        if (!rolling && rigid.velocity.magnitude >= 0.01f)
        {
            rolling = true;
            rollingAudioSource.Play();
        }
        // 如果滚动变慢,停止滚动音效
        else if (rolling && rigid.velocity.magnitude < 0.01f)
        {
            rolling = false;
            rollingAudioSource.Stop();
        }
    }

    // 如果物体停止与其他物体碰撞,会收到此消息
    void OnCollisionExit(Collision collision)
    {
        // 如果物体掉落并停止碰撞,停止滚动的音效
        if (rolling)
        {
            rolling = false;
            impactAudioSource.Stop();
            rollingAudioSource.Stop();
        }
    }
}
  1. 将SphereSounds脚本拖到Sphere1和Sphere2物体上
  2. build测试吧!(戴上耳机才能听到环绕立体效果哦)

空间映射(Spatial mapping)

  1. 将Project面板Holograms文件夹下的Spatial Mapping拖到Hierarchy的空白处
  2. 点击Hierarchy面板中的Spatial Mapping物体, 在Inspector面板中勾选Draw Visual Meshes
  3. build一下看看效果(注意:Capabilities中的Spatial Perception需要勾选)

    模拟器中加载房间效果如下图所示:
    hololens开发教程_hololens属于什么技术[通俗易懂]

效果如下如图


hololens开发教程_hololens属于什么技术[通俗易懂]

房间的三维信息会以线框渲染,试着让小球滚落掉地上! **接下来让你可以将OrigamiCollection移到一个新的位置:** 1. 在Scripts文件夹下创建TapToPlaceParent脚本,并将下面的代码替换

using UnityEngine;

public class TapToPlaceParent : MonoBehaviour
{
    bool placing = false;

    // GazeGestureManager检测到用户的Select手势时调用
    void OnSelect()
    {
        // 检测到Select手势时,切换用户是否在放置模式
        placing = !placing;

        // 如果在放置模式,显示空间映射网格
        if (placing)
        {
            SpatialMapping.Instance.DrawVisualMeshes = true;
        }
        // 如果没在放置模式,隐藏空间映射网格
        else
        {
            SpatialMapping.Instance.DrawVisualMeshes = false;
        }
    }

    void Update()
    {
        // 如果处于放置模式,将物体位置移动到用户凝视的位置
        if (placing)
        {
            // 发射一条只会检测到空间映射网格的射线
            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))
            {
                // 将物体的父物体移动到射线检测到空间映射网格的点
                this.transform.parent.position = hitInfo.point;

                // 将物体朝向用户
                Quaternion toQuat = Camera.main.transform.localRotation;
                toQuat.x = 0;
                toQuat.z = 0;
                this.transform.parent.rotation = toQuat;
            }
        }
    }
}
  1. 将TapToPlaceParent脚本拖到OrigamiCollection物体下的Stage物体
  2. build来测试下吧!
  3. 可以切换不同的房间来试下效果
    hololens开发教程_hololens属于什么技术[通俗易懂]

hololens开发教程_hololens属于什么技术[通俗易懂]


交流群:492325637
洪流学堂,让你快人几步
hololens开发教程_hololens属于什么技术[通俗易懂]

hololens开发教程_hololens属于什么技术[通俗易懂]

今天的文章hololens开发教程_hololens属于什么技术[通俗易懂]分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/85440.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注