1. 创建一个LookPoint指示点
LookPoint配置信息
Image配置信息
调整Image的Rotation Z 为-180度, 为了接下来的进度条 符合大家所熟悉的顺时针慢慢填满.
这里需要先创建一个 Sprite, 称之为lookPoint, 也就是EyeController的焦点位置
这里Material 使用的shader如下,目的是为了让这个指示点始终显示, 即使被物体遮挡.
创建好LookPoint之后, 运行,你会发现视线中心有一个圆圈指示点, 调整Panel的 scale ,让圆圈显示到合适大小, 接下来在代码里处理EyeController的关注事件
2 获取EyeController的关注事件
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class EyeController : MonoBehaviour {
public GameObject cameraRig;
public GameObject image;
public Sprite initSprite;
public Sprite watchingSprite;
// Use this for initialization
private Image img;
private bool isWatching;
private string lastObjName;
private GameObject lastWatchedObj;
public delegate void WatchingObjectDelegate();
public static event WatchingObjectDelegate watchingObject;
void Start () {
img = image.GetComponent<Image>();
}
// Update is called once per frame
void Update()
{
//射线
Ray ray = new Ray(this.transform.position, transform.forward );
RaycastHit hit;//存储发射射线后产生的碰撞信息hit.point /hit.distance /hit.collider
//发生碰撞
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
{
WatchableObject obj = hit.collider.gameObject.GetComponent<WatchableObject>();
if (obj && obj.enabled == true)//有WatchableObject组件的物体,并且组件有效
{
if(lastObjName == obj.name)//为同一个物体
{
img.sprite = watchingSprite;
if (!isWatching)//第一次进入视野
{
if (obj.gameObject.GetComponent<TeleportPointObject>() == null)//如果不是TeleportPoint
{
cloneObject(obj);
}
img.fillAmount = 0f;
isWatching = true;
}
else
{
if (img.fillAmount < 1f)
{
img.fillAmount += 0.00833333333f;
}
else
{
destroyCloneObj();
//注视时间1.5s后
if (obj.gameObject.GetComponent<TeleportPointObject>() != null)//如果是TeleportPoint
{
//cameraRig.transform.position = obj.transform.position;
Vector3 vec = transform.position - cameraRig.transform.position; //先计算偏移量
Vector3 newPos = obj.transform.position;//获取新的position
newPos.y = transform.position.y;//Eye的Y值并不改变
transform.position = newPos;//设置Eye的新position
cameraRig.transform.position = transform.position - vec;//调整cameraRig的position,防止定位重新改变Eye的位置
}
if (EyeController.watchingObject == null)
{
EyeController.watchingObject += obj.WatchingObjectDelegate;
}
watchingObject();
}
}
}else
{
lastObjName = obj.name;
initImage();
destroyCloneObj();
if(EyeController.watchingObject != null)
{
EyeController.watchingObject -= obj.WatchingObjectDelegate;
}
}
}else//为其他Collider ,但是没有WatchableObject组件
{
initImage();
destroyCloneObj();
EyeController.watchingObject = null;
}
}else//没有碰撞
{
initImage();
destroyCloneObj();
EyeController.watchingObject = null;
}
}
//还原image为初始状态
private void initImage()
{
if (img.type == Image.Type.Filled)
{
img.fillAmount = 1f;
img.sprite = initSprite;
}
isWatching = false;
}
//克隆物体
private void cloneObject(WatchableObject collidedItem)
{
GameObject cloneObj = Object.Instantiate(collidedItem.transform.gameObject, collidedItem.transform.position, collidedItem.transform.rotation) as GameObject;
if (collidedItem.transform.parent)
{
cloneObj.transform.SetParent(collidedItem.transform.parent);
cloneObj.transform.localScale = collidedItem.transform.localScale;
}
foreach (Component comp in cloneObj.GetComponents<Component>())
{
if (!(comp is Transform) && !(comp is Renderer))
{
Destroy(comp);
}
}
Shader shader = Shader.Find("Valve/VR/Silhouette");
Material material = new Material(shader);
material.name = "silhouette";
material.SetColor("g_vOutlineColor", Color.green);
cloneObj.GetComponent<Renderer>().material = material;
lastWatchedObj = cloneObj;
}
//销毁克隆的物体
private void destroyCloneObj()
{
if (lastWatchedObj)
{
Destroy(lastWatchedObj);
}
}
}