本文主要是介绍HTC Vive交互开发——凝视效果实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
凝视效果相关:
- 通过跟踪头部移动,设置一个代表光标的准星,当停留在某处足够长的时间之后,激发选中逻辑。
- 类似Kinect自然语言交互。
- 多用于移动VR,如Cardboard、GearVR等。
- VIVE平台使用凝视效果可以增强用户体验。
凝视效果实现原理
1. 基于射线原理,通过Raycast判断击中的物体,在Update里面进行逻辑判断;2. 准星或者十字线基于UGUI,设置为相机的子物体,等待操作过程一般为圆环逐渐填充动画或者进度条动画;3. 被凝视的物体可以是动画也可以是UI;4. 如果在一段时间内击中的物体是同一个物体,则认为该元素被选中,在此逻辑内撰写相应处理函数,如消失、变换材质、移动、缩放等;5. 元素一般分为三个状态响应:准星进入、准星退出、准星停留时间到。
凝视效果时间示例
- 使元素响应视线进入、退出;
- 凝视按钮一段时间后实现点击,使其消失;
- 凝视一个cube,经过一段时间后用眼神击中它;
- 是准星垂直于物体表面。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class GazeController : MonoBehaviour {/// <summary>/// 准星容器/// </summary>public Canvas reticleCanvas;/// <summary>/// 准星图片/// </summary>public Image reticleImage;/// <summary>/// 选中的目标/// </summary>private GameObject target;private Vector3 originPos;/// <summary>/// 初始缩放/// </summary>private Vector3 originScale;/// <summary>/// 倒计时时间/// </summary>private float countDownTime=2;/// <summary>/// 但当前时间/// </summary>private float nowTime=0;// Use this for initializationvoid Start (){reticleImage.fillAmount = 0;originPos = reticleCanvas.transform.localPosition;originScale = reticleCanvas.transform.localScale;}// Update is called once per framevoid Update (){Ray ray = new Ray(transform.position, transform.forward);RaycastHit hit;if (Physics.Raycast(ray,out hit,150)){reticleCanvas.transform.position = hit.point;reticleCanvas.transform.localScale = originScale * hit.distance;//准星与击中点的法线方向保持一致reticleCanvas.transform.forward = hit.normal;if (hit.transform.gameObject!=target){if (target!=null){GazeItem oldItem = target.GetComponent<GazeItem>();if (oldItem){oldItem.OnGazeOut();}}//视线初次进入的处理target = hit.transform.gameObject;GazeItem newItem = target.GetComponent<GazeItem>();if (newItem){newItem.OnGazeIn();}}// 视线停留else{nowTime += Time.deltaTime;if ((countDownTime-nowTime)>0){//尚未达到激活条件reticleImage.fillAmount = nowTime / countDownTime;}else{//达到激活条件GazeItem gazeFireItem = target.GetComponent<GazeItem>();if (gazeFireItem){gazeFireItem.OnGazeFire(hit);}nowTime = 0;}}}else{reticleCanvas.transform.localPosition = originPos;reticleCanvas.transform.localScale = originScale;reticleCanvas.transform.forward = Camera.main.transform.forward;reticleImage.fillAmount = 0;}}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;public class GazeItem : MonoBehaviour {public Material highLightMat;public Material normalMat;// Use this for initializationvoid Start (){}// Update is called once per framevoid Update (){}/// <summary>/// 视线移入处理函数/// </summary>public void OnGazeIn(){if (gameObject.tag=="GazeUI"){ExecuteEvents.Execute(gameObject, new PointerEventData(EventSystem.current), ExecuteEvents.pointerEnterHandler);}else if (gameObject.tag=="GazeObject"){gameObject.GetComponent<Renderer>().material = highLightMat;}}/// <summary>/// 视线移出处理函数/// </summary>public void OnGazeOut(){if (gameObject.tag == "GazeUI"){ExecuteEvents.Execute(gameObject, new PointerEventData(EventSystem.current), ExecuteEvents.pointerExitHandler);}else if (gameObject.tag == "GazeObject"){gameObject.GetComponent<Renderer>().material = normalMat;}}/// <summary>/// 视线凝视处理函数/// </summary>public void OnGazeFire(RaycastHit hit){if (gameObject.tag == "GazeUI"){gameObject.SetActive(false);}else if (gameObject.tag == "GazeObject"){gameObject.GetComponent<Rigidbody>().AddForceAtPosition(hit.point.normalized*150,hit.point);}}
}
这篇关于HTC Vive交互开发——凝视效果实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!