前言:搭建好Hololens的开发环境后,新建一个GameObject用于挂载脚本(GazeManager.cs)。
这一篇的内容只是通过根据用户当前是否看着物体来决定显示的光标类型。
导入官方的HoloToolkit(详细见https://github.com/Microsoft/MixedRealityToolkit-Unity)。
1.GazeManager.cs:以Hololens为起点,设定长度的射线与指定层级的物体接触时,返回信息,让脚本知道与物体发生接触。
using HoloToolkit.Unity;
using UnityEngine;
namespace Academy.HoloToolkit.Unity{
public class GazeManager :Singleton<GazeManager>{
[HideInInspector] public bool Hit;
/// <summary>
/// Position记录射线与物体接触的坐标位置;
/// Normal记录法线;
/// </summary>
[HideInInspector] public Vector3 Position, Normal;
[HideInInspector]public RaycastHit HitInfo {get; private set;}
public float MaxGazeDistance = 15.0f;
[Tooltip("指定层级的物体会产生碰撞")]
public LayerMask RaycastLayerMask = Physics.DefaultRaycastLayers;
/// <summary>
/// gazeOrigin保存Hololens的位置;
/// gazeDirection保存Hololens的正面朝向;
/// </summary>
private Vector3 gazeOrigin, gazeDirection;
private float lastHitDistance = 15.0f;
void Update(){
gazeOrigin = Camera.main.transform.position;
gazeDirection = Camera.main.transform.forward;
UpdateRaycast();
}
void UpdateRaycast(){
RaycastHit hitInfo;
Hit = Physics.Raycast(gazeOrigin, gazeDirection, out hitInfo, MaxGazeDistance, RaycastLayerMask);
HitInfo = hitInfo;
if(Hit){
Position = hitInfo.point;
Normal = hitInfo.normal;
lastHitDistance = hitInfo.distance;
}
else{
Position = gazeOrigin + (gazeDirection * lastHitDistance);
Normal = gazeDirection;
}
}
}
}
当GazeManager.cs的射线接触到指定层级的物体时,公共变量public bool Hit 为true,那么CursorManager.cs通过这一变量来决定让那个状态的Cursor显示,既可以检测GazeManager.cs是否正常工作。
using HoloToolkit.Unity;
using UnityEngine;
namespace Academy.HoloToolkit.Unity{
public class CursorManager : Singleton<CursorManager> {
public GameObject CursorOnHolograms, CursorOffHolograms;
public float DistanceFromCollision = 0.01f;
void Awake(){
if(CursorOffHolograms == null || CursorOnHolograms == null){ Debug.Log(this.name + " -> CursorManager.cs don't have enough parameter."); return;}
CursorOffHolograms.SetActive(false);
CursorOnHolograms.SetActive(false);
}
void LateUpdate(){
if(GazeManager.Instance == null || CursorOffHolograms == null || CursorOnHolograms == null){ Debug.Log(this.name + " -> CursorManager.cs don't have enough parameter. LateUpdate();"); return;}
if(GazeManager.Instance.Hit){
CursorOffHolograms.SetActive(false);
CursorOnHolograms.SetActive(true);
}
else{
CursorOnHolograms.SetActive(false);
CursorOffHolograms.SetActive(true);
}
// 更新Cursor的位置和法线
this.gameObject.transform.position = GazeManager.Instance.Position + GazeManager.Instance.Normal * DistanceFromCollision;
gameObject.transform.up = GazeManager.Instance.Normal;
}
}
}