Cardboard是我接触VR开发最初接触到的SDK,因为对硬件和开发的要求比较低,所以很多的VR小游戏和应用(观影为主)都会基于Cardboard进行开发,但由于硬件设备的限制在用户交互上都会使用凝视的方式进行交互,SDK里自带的凝视方式使用不是很灵活,效果也比较单一,所以就自己从新按照需求实现了凝视的交互方式,用到的都是射线碰撞和UGUI的基础知识,实现的方法也比较简单。
首先我们要实现的效果是,当使用者在虚拟场景中看向某各3DUI时出现一个图标,并出现加载的效果,在加载完成后执行相应的操作,这里我用UGUI来实现。
第一步,在场景中创建一个Canvas并且把渲染模式设置为WorldSpace,这样你的UI对象将在场景中进行渲染,你可以把它拖动到你需要的位置
创建一个image,添加按钮相应的贴图,这里我要实现的是一个圆形的贴图,凝视后开始加载,并且在凝视的部位出现一个光标
接下来再添加一个image作为这个按钮的遮罩,将遮罩image的类型设置为filed,fill method方式设置为360度旋转填充
然后在当前按钮image上添加一个2D的碰撞器(其实3D的压扁也可以),用来执行后面的碰撞检测
最后在场景中创建一个红色的小球作为凝视的光标,位置啥的不重要,只要大小合适够醒目就行,反正一开始就要被隐藏掉
接下来就是代码部分了
public GamObject headCamera;
public GameObject cursor ;
public Image button_ui_bg;
private int targetMask;
void Start()
{
cuisor.SetActive(false);
targetMask = LayerMask.GetMask("Ray");
print(targetMask);
}
从外部获取从SDK中添加的头部摄像机,按钮以及小球,设置一个层蒙版用作射线检测,只有碰撞到UI物体的时候才出现光标
接下来在update函数中实现碰撞检测,当射线碰撞到UI物体上的·碰撞器时遮罩image开始加载,加载完成后执行相应操作
void Update()
{
Ray ray = new Ray(camera_1.transform.position, headCamera.transform.forward);
if (Physics.Raycast(ray, out hit, 1000f, targetMask))
{
qui.SetActive(true);
qui.transform.position = hit.point;
GazeUI(hit.collider.gameObject.name);
}
else
{
qui.SetActive(false);
button_ui_bg.fillAmount = 0;
}
}
public void GazeUI(string name)
{
if (name == "button_01")
{
button_ui_bg.fillAmount += Time.deltaTime;
if (button_ui_bg.fillAmount >= 1f)
{
SceneManager.LoadScene("Loading");
}
}
else
{
button_ui_bg].fillAmount = 0;
}
}
这样就基本完成了,如果你需要不同的效果,也可以选择不同的UI物体