1.前言
本文基于InputModule的逻辑,根据VR的操作特点,写一个VrInputModule。
2.Input
虚拟一个Input类,来获取最基本的信息,如下代码所示(示意代码):
using UnityEngine;
using System.Collections;
public class GazeInput : MonoBehaviour
{
public Vector2 GetGazePosition()
{
return new Vector2(Screen.width/2, Screen.height/2);
}
public Vector2 GetGazeDelta()
{
//TODO:Get position delta or rotation delta;
return new Vector2(0, 0);
}
}
3.自定义InputModule
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class GazeInputModule : BaseInputModule
{
[SerializeField]
private float dragThreshold = 10;
private PointerEventData pointer;
private GazeInput gaze;
private GazeInput gazeInput
{
get
{
if (gaze == null)
{
gaze = GetComponent<GazeInput>();
}
return gaze;
}
}
private PointerEventData GetGazePointerEventData(out bool pressed,out bool released)
{
if (pointer == null)
{
pointer = new PointerEventData(eventSystem);
pointer.dragging = false;
}
pressed = PressedThisFrame();
released = ReleasedThisFrame();
pointer.position = gazeInput.GetGazePosition();
pointer.delta = gazeInput.GetGazeDelta();
eventSystem.RaycastAll(pointer, m_RaycastResultCache);
pointer.pointerCurrentRaycast = FindFirstRaycast(m_RaycastResultCache);
m_RaycastResultCache.Clear();
return pointer;
}
private void ProcessGazePress(PointerEventData pointerData, bool pressed, bool released)
{
GameObject currentOverGo = pointerData.pointerCurrentRaycast.gameObject;
if (pressed)
{
pointerData.eligibleForClick = true;
pointer.dragging = false;
pointerData.pressPosition = pointerData.position;
pointerData.pointerPressRaycast = pointerData.pointerCurrentRaycast;
//Selected and deselected event are neglected
GameObject newPressed = ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerData, ExecuteEvents.pointerDownHandler);
if (newPressed == null)
{
newPressed = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
}
pointerData.pointerPress = newPressed;
pointerData.rawPointerPress = currentOverGo;
pointerData.pointerDrag = ExecuteEvents.GetEventHandler<IDragHandler>(currentOverGo);
if (pointerData.pointerDrag != null)
{
ExecuteEvents.Execute(pointerData.pointerDrag, pointerData, ExecuteEvents.initializePotentialDrag);
}
}
if (released)
{
ExecuteEvents.Execute(pointerData.pointerPress, pointerData, ExecuteEvents.pointerUpHandler);
GameObject pointerClickHandler = ExecuteEvents.GetEventHandler<IPointerClickHandler>(currentOverGo);
if (pointerData.pointerPress == pointerClickHandler && pointerData.eligibleForClick)
{
ExecuteEvents.Execute(pointerData.pointerPress, pointerData, ExecuteEvents.pointerClickHandler);
}
else if(pointerData.pointerDrag != null && pointerData.dragging)
{
ExecuteEvents.ExecuteHierarchy(currentOverGo, pointerData, ExecuteEvents.dropHandler);
}
pointerData.eligibleForClick = false;
pointerData.pointerPress = null;
pointerData.rawPointerPress = null;
if (pointerData.pointerDrag != null && pointerData.dragging)
ExecuteEvents.Execute(pointerData.pointerDrag, pointerData, ExecuteEvents.endDragHandler);
pointerData.dragging = false;
pointerData.pointerDrag = null;
if (currentOverGo != pointerData.pointerEnter)
{
HandlePointerExitAndEnter(pointerData, null);
HandlePointerExitAndEnter(pointerData, currentOverGo);
}
}
}
private void ProcessMove(PointerEventData pointerData)
{
HandlePointerExitAndEnter(pointerData, pointerData.pointerCurrentRaycast.gameObject);
}
private void ProcessDrag(PointerEventData pointerData)
{
if (!ShoundProcessDrag(pointerData))
return;
if (!pointerData.dragging)
{
ExecuteEvents.Execute(pointerData.pointerDrag, pointerData, ExecuteEvents.beginDragHandler);
pointerData.dragging = true;
}
if (pointerData.dragging)
{
if (pointerData.pointerPress != pointerData.pointerDrag)
{
ExecuteEvents.Execute(pointerData.pointerPress, pointerData, ExecuteEvents.pointerUpHandler);
pointerData.eligibleForClick = false;
pointerData.pointerPress = null;
pointerData.rawPointerPress = null;
}
ExecuteEvents.Execute(pointerData.pointerDrag, pointerData, ExecuteEvents.dragHandler);
}
}
public override void Process()
{
bool pressed, released;
PointerEventData eventData = GetGazePointerEventData(out pressed, out released);
ProcessGazePress(eventData, pressed, released);
if (!eventData.dragging)
{
ProcessMove(eventData);
}
if (!released)
{
ProcessDrag(eventData);
}
}
private bool PressedThisFrame()
{
return Input.GetKeyDown(KeyCode.KeypadEnter);
}
private bool ReleasedThisFrame()
{
return Input.GetKeyUp(KeyCode.KeypadEnter); ;
}
private bool ShoundProcessDrag(PointerEventData pointerData)
{
return Mathf.Abs(pointerData.delta.x) > dragThreshold || Mathf.Abs(pointerData.delta.y) > dragThreshold;
}
}
4.结语
强迫症晚期,没有结语。。。。。。。。