Create a gameobject called line which has the linerenderer for the pointer and a camera that is disabled and has a FOV of 1. then use this code in a custom input module. CasterRight is the camera on the right controller pointer. I do this for both left and right hands. Use this as a replacement for InputModule. I also put a script on each canvas that adds itself to the Canvases list. Most of it is derived from VR Andrew’s tutorial video that explains how to do it.
public Camera CasterRight;
public Camera CasterLeft;
[HideInInspector]
public List Canvases;
public GameObject RightCurrent;
public GameObject LeftCurrent;
GameObject RightPressed;
GameObject LeftPressed;
public PointerEventData RightData { get; private set; }
public PointerEventData LeftData { get; private set; }
private void ProcessRight()
{
if (ControllerManager.Right.GetState() != ControllerState.Unavailable && CasterRight != null)
{
//set camera for canvases to right camera
foreach (Canvas canvas in Canvases)
{
canvas.worldCamera = CasterRight;
}
//reset data
RightData.Reset();
RightData.position = new Vector2(CasterRight.pixelWidth / 2, CasterRight.pixelHeight / 2);
//Raycast
eventSystem.RaycastAll(RightData, m_RaycastResultCache);
RightData.pointerCurrentRaycast = FindFirstRaycast(m_RaycastResultCache);
RightCurrent = RightData.pointerCurrentRaycast.gameObject;
//clear raycast
m_RaycastResultCache.Clear();
//handle hover
HandlePointerExitAndEnter(RightData, RightCurrent);
//handle press
if (ControllerManager.Right.IsPressed(Buttons.Trigger))
{
OnPressRight();
}
//handle release
else
{
OnReleaseRight();
}
}
}
void OnPressRight()
{
//set raycast
RightData.pointerPressRaycast = RightData.pointerCurrentRaycast;
//check for object hit and send down event
GameObject newPointerPress = ExecuteEvents.ExecuteHierarchy(RightCurrent, RightData, ExecuteEvents.pointerDownHandler);
//if no down handler , try and get click handler
if (newPointerPress == null)
{
newPointerPress = ExecuteEvents.GetEventHandler(RightCurrent);
}
if (RightPressed != null && RightCurrent == null)
{
//if we exit the element and still have button pressed send up event
ExecuteEvents.Execute(RightPressed, RightData, ExecuteEvents.pointerUpHandler);
}
//set RightData
RightData.pressPosition = RightData.position;
RightData.pointerPress = newPointerPress;
RightData.rawPointerPress = RightCurrent;
RightPressed = newPointerPress;//save pressed element for later use when released
}
void OnReleaseRight()
{
ExecuteEvents.Execute(RightData.pointerPress, RightData, ExecuteEvents.pointerUpHandler);
GameObject pointerUpHandler = ExecuteEvents.GetEventHandler(RightCurrent);
if (RightData.pointerPress == pointerUpHandler)
{
//send up event to handler under cursor
ExecuteEvents.Execute(RightData.pointerPress, RightData, ExecuteEvents.pointerUpHandler);
}
if(RightPressed != null && pointerUpHandler == RightPressed)
{
//if we are still over the one we first pressed send click event
ExecuteEvents.Execute(RightPressed, RightData, ExecuteEvents.pointerClickHandler);
Debug.Log("Clicked - " + RightPressed);
}
//clear selected gameobject
eventSystem.SetSelectedGameObject(null);
//reset RightData
RightData.pressPosition = Vector2.zero;
RightData.pointerPress = null;
RightData.rawPointerPress = null;
RightPressed = null;
}
David Watt
Hollow World Games