VR最原始的人机交互方式-凝视瞄准头控操作,
通过屏幕中央的cursor瞄准点瞄准ui界面或物体,自动点击进入或手柄触摸板点击,实现的核心步骤:
// Cast a ray into the scene
pointerData.Reset();
pointerData.position = new Vector2(hotspot.x * Screen.width, hotspot.y * Screen.height);
eventSystem.RaycastAll(pointerData, m_RaycastResultCache);
m_RaycastResultCache = m_RaycastResultCache.OrderBy(o => o.distance).ToList();
//If the Canvas and an Element are Z-Fighting, remove the Canvas from the runnings
if ((m_RaycastResultCache.Count > 1) && (m_RaycastResultCache[0].gameObject.GetComponent<Canvas>()) && (Mathf.Abs(m_RaycastResultCache[0].distance - m_RaycastResultCache[1].distance)) < 0.1f)
{
m_RaycastResultCache.RemoveAt(0);
}
for(int i=m_RaycastResultCache.Count-1; i>=0; i--)
{
if(m_RaycastResultCache[i].gameObject.tag == "GazeReticleDisable")
{
m_RaycastResultCache.RemoveAt(i);
}
}
pointerData.pointerCurrentRaycast = FindFirstRaycast(m_RaycastResultCache);
m_RaycastResultCache.Clear();
射线检测,按距离排序或剔除
// 凝视悬停点击
if (go)
{
if (go == previousGazedObject)
{
if (Time.time - lastTime > DetTime)
{
lastTime = Time.time;
// 触发点击事件
GameObject handler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(pointerData.pointerEnter);
if (handler != null)
{
ExecuteEvents.ExecuteHierarchy(handler, pointerData, ExecuteEvents.pointerClickHandler);
}
if(!IsOverGaze)
{
IsOverGaze = true;
// 触发mousedown 并为拖动准备数据
HandleTrigger();
}
}
}
else
{
IsOverGaze = false;
lastTime = Time.time;
// 触发mouseup
HandlePendingClick();
}
}
else
{
// 触发mouseup
HandlePendingClick();
}
倒计时发出点击事件
void UpdateReticle(GameObject previousGazedObject) {
GameObject gazeObject = GetCurrentGameObject(); // Get the gaze target
if (gazeObject)
{
if(gazeObject.tag == "GazeDisable")
{
m_Reticle.Hide();
}
else
{
m_Reticle.Show();
}
if (m_Reticle)
m_Reticle.SetPosition(GetIntersectionPosition(), GetIntersectionDistace());
if(gazeObject == previousGazedObject)
{
GameObject handler = ExecuteEvents.GetEventHandler<IPointerDownHandler>(gazeObject);
if (m_SelectionRadial && (handler != null || gazeObject.tag == "GazeReticleEnable"))
m_SelectionRadial.HandleDown();
}
else
{
if (m_SelectionRadial)
m_SelectionRadial.HandleUp();
}
}
else
{
m_Reticle.Show();
if (m_Reticle)
m_Reticle.SetPosition();
if (m_SelectionRadial)
m_SelectionRadial.HandleUp();
}
}
cursor动画