unity VR凝视gaze
带上VR头显,盯着物体就有个进度条,等待完成,就可以做一些炫酷的技巧,很多VR的SDK也有这个技能,其原理是用视线来探测,下面贴出代码新建脚本命名GazeController;//准星容器publicCanvas rectileCanvas;//进度文字public Text rectileText;//准星通过属性面板拖拽 进行赋值publicIma...
·
带上VR头显,盯着物体就有个进度条,等待完成,就可以做一些炫酷的技巧,
很多VR的SDK也有这个技能,其原理是用视线来探测,下面贴出代码
新建脚本命名GazeController;
//准星容器
public Canvas rectileCanvas;
//进度文字
public Text rectileText;
//准星 通过属性面板拖拽 进行赋值
public Image rectileImage;
//击中的当前目标
public GameObject Target;
//初始位置
private Vector3 originPos;
//初始缩放
private Vector3 originScale;
//倒计时
private float countDownTime=3;
//当前时间
private float currentTime=0;
bool isdone=false;
void Start () {
//初始填充
rectileImage.fillAmount = 0;
//初始位置
originPos = rectileCanvas.transform.position;
//初始缩放
originScale=rectileCanvas.transform.localScale;
}
// Update is called once per frame
void Update () {
Ray ray = new Ray (transform.position, transform.forward);
RaycastHit hit;
//如果碰到物体
//LineRenderer a; 调试距离
// a = GetComponent<LineRenderer> (); 获取当前组件
//a.SetPosition (0, transform.position);
if (Physics.Raycast (ray, out hit, 3))
{ // Vector3 LonDis = new Vector3 (0.3f,0.1f,0.3f);
//a.SetPosition (1, hit.point); 设置终点
//保持一些距离可以让它不闪烁
//碰撞的位置给准星
//rectileCanvas.transform.position =hit.point + LonDis;
//根据距离进行缩放,补偿3d世界中近大远小的情况
// rectileCanvas.transform.localScale=originScale*hit.distance;
//rectileText.transform.position = rectileImage.transform.position;
//让准星与碰撞的物体垂直通过让准星与击中点法线方向一致
//rectileCanvas.transform.forward=Camera.main.transform.forward;
//视线初次进入;
if (hit.transform.tag == "GazeUI" || hit.transform.tag == "GazeObj") {
rectileCanvas.gameObject.SetActive (true);
} else
{
//视线移出时,做一些初始化
currentTime = 0;
rectileCanvas.gameObject.SetActive (false);
}
if (hit.transform.gameObject != Target)
{
if (Target != null)
{
VRGazeItem oldItem = Target.GetComponent<VRGazeItem> ();
if (oldItem)
{
oldItem.GazeOut ();
}
}
Target = hit.transform.gameObject;
VRGazeItem newItem = Target.GetComponent<VRGazeItem> ();
if (newItem)
{
//凝视
newItem.GazeIn();
}
}
else //视线在此停留
{
currentTime += Time.deltaTime;
//设定等待时间未结束
if (countDownTime - currentTime > 0 )
{
rectileImage.fillAmount = currentTime / countDownTime;
rectileText.text = Mathf.Ceil(rectileImage.fillAmount*100)+"%";
rectileText.transform.forward = Camera.main.transform.forward;
//rectileText.transform.localPosition = rectileCanvas.transform.position;
}
else//达到设定条件(3秒后)
{
//VRGazeItem 为对象身上挂载的功能函数,
VRGazeItem gazeFireItem = Target.GetComponent<VRGazeItem> ();
if (gazeFireItem)
{
gazeFireItem.GazeFire (hit);
}
rectileCanvas.gameObject.SetActive (false);
}
}
}
else
//没有碰到物体
{
rectileCanvas.gameObject.SetActive (false);
// rectileCanvas.transform.position = originPos; //缩放复位
rectileCanvas.transform.localScale=originScale;
// rectileCanvas.transform.forward = Camera.main.transform.forward;
rectileImage.fillAmount = 0;
}
}
}
gazeItem脚本 有3个交互,GazeIn 方法 和GazeOut 以及GazeFire。 具体 实现看不同的需求。
如果需要 和物体 交互可以 用下面这个 接口
interface IRayInteractor
{
/// <summary>
/// 射线 停留的物体
/// </summary>
GameObject TempObj
{
get;
}
/// <summary>
/// 需要 停留的时间 触发 停留事件
/// </summary>
float NeedStayTime
{
get
;
set;
}
/// <summary>
/// 停留的时间
/// </summary>
float StayTime { get; }
/// <summary>
/// 射线进入
/// </summary>
/// <param name="temp">射线凝视的物体</param>
void OnRayEnter(GameObject temp);
/// <summary>
/// 射线离开
/// </summary>
void OnRayExit();
/// <summary>
/// 射线停留
/// </summary>
void OnRayStay();
}
更多推荐
已为社区贡献1条内容
所有评论(0)