天天看点

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

瞅我干嘛?瞅你咋的?谁惹我,我盯谁,盯谁杀谁。神挡杀神,佛挡杀佛。--------眼神杀,htc vive的凝视效果

1、删除场景中的maincamera,创建一个Plane并设置属性

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

2、创建一个cube并设置相关属性

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)
Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

3、创建一个Canvase并设置相关属性

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

4、创建一个Button,作为Canvase的子物体,并设置相关属性

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)
Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

5、将SteamVR Plugins导入到unity,然后将CameraGig拖动到Hierarchy视图并设置相关属性

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

6、创建一个Canvas,作为Camera(eye)的子物体并设置相关属性

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

7、创建一个Image,作为Canvase的子物体,用来存放准星,并设置相关属性

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

8、再创建一个Image,作为上一步的image的子物体,用来存放准星的半透明的背景,并设置相关属性

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

9、创建两个脚本,GazeController挂载到Camera(eye)上,VRGazeItem分别挂载到cube和button上

碰撞到物体,将准星移动到视线接触到的位置,准星与物体垂直,并且进度条根据计时更改进度

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)
Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

②如果是视线第一次看见这个物体,并且物体身上有凝视组件,进行凝视操作

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

cube凝视进入时变成蓝色,button凝视时执行虚拟鼠标进入的方法,button设置了在鼠标进入时的蓝色背景,所以凝视时显示变成蓝色

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)
Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

如果眼神接触另一个物体前,上一个物体上有凝视组件,则进行移出操作,视线从button上离开时,button执行鼠标移出的方法,变成正常色,视线从cube上离开时,cube也变成正常的白色

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)
Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

10、当视线在物体上停留时,进行凝视操作。button消失,cube作用一个力,进行移动

凝视前cube的位置

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

凝视时cube的右边那个角被抬高了

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

凝视前button的位置

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

凝视后button消失

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

11、VRGazeItem.cs的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class VRGazeItem : MonoBehaviour {

    //高亮材质
    public Material highlightMat;
    //正常材质
    public Material normalMat;

	
	void Start () {
		
	}
	
	
	void Update () {
		
	}

    //视线移入处理函数
    public void GazeIn()
    {
        if(gameObject.tag == "GazeUI")
        {
            //鼠标移入的效果
            ExecuteEvents.Execute(gameObject,new PointerEventData(EventSystem.current),ExecuteEvents.pointerEnterHandler);
        }else if(gameObject.tag == "GazeObj")
        {
            //给cube添加高亮时变成蓝色
            gameObject.GetComponent<Renderer>().material = highlightMat;
        }

    }

    //视线移出处理函数
    public void GazeOut()
    {
        if (gameObject.tag == "GazeUI")
        {
            //鼠标移入的效果
            ExecuteEvents.Execute(gameObject, new PointerEventData(EventSystem.current), ExecuteEvents.pointerExitHandler);
        }
        else if (gameObject.tag == "GazeObj")
        {
            //cube变成正常的颜色
            gameObject.GetComponent<Renderer>().material = normalMat;
        }
    }

    //视线激活处理函数
    public void GazeFire(RaycastHit hit)
    {
        if (gameObject.tag == "GazeUI")
        {
            //隐藏物体
            gameObject.SetActive(false);
        }
        else if (gameObject.tag == "GazeObj")
        {
            //给物体cube作用一个力
            gameObject.GetComponent<Rigidbody>().AddForceAtPosition(hit.point.normalized*100,hit.point);
        }

    }
}
           

12、GazeController.cs的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GazeController : MonoBehaviour {

    //准星容器
    public Canvas reticleCanvas;
    //准星
    public Image reticleImage;
    //击中的当前目标
    public GameObject target;
    //初始位置
    private Vector3 originPos;
    //初始缩放
    private Vector3 originScale;
    //倒计时时间
    private float countDownTime = 3;
    //当前时间
    private float currentTime = 0;

	// Use this for initialization
	void Start () {
        reticleImage.fillAmount = 0;
        //记录初始位置
        originPos = reticleCanvas.transform.localPosition;
        //记录初始缩放
        originScale = reticleCanvas.transform.localScale;
	}
	
	// Update is called once per frame
	void Update () {
        Ray ray = new Ray(transform.position, transform.forward);
        RaycastHit hit;
        //如果碰撞到了物体
        if (Physics.Raycast(ray, out hit, 50))
        {
            //将碰撞的位置赋给准星
            reticleCanvas.transform.position = hit.point;
            //根据距离进行缩放,补偿在3d世界中近大远小的情况
            reticleCanvas.transform.localScale = originScale * hit.distance;

            //让准星与碰撞的物体垂直通过让准星与击中点法线方向一致
            reticleCanvas.transform.forward = hit.normal;
            //视线初次进入
            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)
                {
                    //设置进度条
                    reticleImage.fillAmount = currentTime / countDownTime;
                }
                else//达到设定条件
                {
                    currentTime = 0;
                    //如果
                    VRGazeItem gazeFireItem = target.GetComponent<VRGazeItem>();
                    if (gazeFireItem)
                    {
                        gazeFireItem.GazeFire(hit);
                    }
                }
            }
        }
        //没有碰撞到物体
        else
        {
            reticleCanvas.transform.position = originPos;
            //缩放复位
            reticleCanvas.transform.localScale = originScale;
            //准星方向复位
            reticleCanvas.transform.forward = Camera.main.transform.forward;
            reticleImage.fillAmount = 0;
        }
    }
}
           

注:1、参考资料:http://edu.manew.com/course/344/learn#lesson/5606

2、遇到的问题:当准星与物体接触时,不停闪动

原因:unity本身的问题,当两个物体接触时,会发生闪动的问题

解决办法:给物体添加一个shader

①创建一个Matirial,Create-->Material-->重命名“UIMaterial”

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

②将“UIOverlay”拖动进unity

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

③选择材质UIMaterial,在Shader下拉框选项中选择UI-->Overlay

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)

④分别为两个image添加material

Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)
Htc Vive入门之凝视效果(眼神杀,遇神杀神,遇佛杀佛)