帶上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();
}