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);
}
}
}