/// <summary>
        /// Adds necessary components to Vive controller gameobjects. These will let us know what inputs are used on them.
        /// </summary>
        private void SetupControllers()
        {
            //Find Controller manager on the scene.
            if (controllerManager == null)
            {
                controllerManager = Object.FindObjectOfType <SteamVR_ControllerManager>();
                if (controllerManager == null)
                {
                    Debug.LogError("Can't find SteamVR_ControllerManager on scene. It is required to use VIVE control method. Make sure all SteamVR prefabs are present.");
                }
            }

            //attach assistant scripts to cui objects.
            if (rightCont == null)
            {
                CurvedUIViveController viveCont = controllerManager.right.GetComponent <CurvedUIViveController>();
                if (viveCont == null)
                {
                    viveCont = controllerManager.right.AddComponent <CurvedUIViveController>();
                }
                rightCont = viveCont;
            }

            if (leftCont == null)
            {
                CurvedUIViveController viveCont = controllerManager.left.GetComponent <CurvedUIViveController>();
                if (viveCont == null)
                {
                    viveCont = controllerManager.left.AddComponent <CurvedUIViveController>();
                }
                leftCont = viveCont;
            }
        }
        /// <summary>
        /// Processes Events from given controller.
        /// </summary>
        /// <param name="myController"></param>
        void ProcessController(GameObject myController)
        {
            //do not process events from this controller if it's off or not visible by base stations.
            if (!myController.gameObject.activeInHierarchy)
            {
                return;
            }

            CurvedUIViveController myControllerAssitant = myController.GetComponent <CurvedUIViveController>();

            if (myControllerAssitant == null)
            {
                myControllerAssitant = myController.AddComponent <CurvedUIViveController>();
            }

            // send update events if there is a selected object - this is important for InputField to receive keyboard events
            SendUpdateEventToSelectedObject();

            // see if there is a UI element that is currently being pointed at
            PointerEventData ControllerData;

            if (myControllerAssitant == rightCont)
            {
                ControllerData = GetControllerPointerData(myControllerAssitant, ref rightControllerData);
            }
            else
            {
                ControllerData = GetControllerPointerData(myControllerAssitant, ref leftControllerData);
            }

            currentPointedAt = ControllerData.pointerCurrentRaycast.gameObject;

            ProcessDownRelease(ControllerData, myControllerAssitant.IsTriggerDown, myControllerAssitant.IsTriggerUp);

            if (!myControllerAssitant.IsTriggerUp)
            {
                ProcessMove(ControllerData);
                ProcessDrag(ControllerData);
            }

            if (!Mathf.Approximately(ControllerData.scrollDelta.sqrMagnitude, 0.0f))
            {
                var scrollHandler = ExecuteEvents.GetEventHandler <IScrollHandler>(ControllerData.pointerCurrentRaycast.gameObject);
                ExecuteEvents.ExecuteHierarchy(scrollHandler, ControllerData, ExecuteEvents.scrollHandler);
                // Debug.Log("executing scroll handler");
            }
        }
        /// <summary>
        /// Create a pointerEventData that stores all the data associated with Vive controller.
        /// </summary>
        private CurvedUIPointerEventData GetControllerPointerData(CurvedUIViveController controller, ref CurvedUIPointerEventData ControllerData)
        {
            if (ControllerData == null)
            {
                ControllerData = new CurvedUIPointerEventData(eventSystem);
            }

            ControllerData.Reset();
            ControllerData.delta        = Vector2.one;                                           // to trick into moving
            ControllerData.position     = Vector2.zero;                                          // this will be overriden by raycaster
            ControllerData.Controller   = controller.gameObject;                                 // raycaster will use this object to override pointer position on screen. Keep it safe.
            ControllerData.scrollDelta  = controller.TouchPadAxis - ControllerData.TouchPadAxis; // calcualte scroll delta
            ControllerData.TouchPadAxis = controller.TouchPadAxis;                               // assign finger position on touchpad

            eventSystem.RaycastAll(ControllerData, m_RaycastResultCache);                        //Raycast all the things!. Position will be overridden here by CurvedUIRaycaster

            //Get a current raycast to find if we're pointing at GUI object.
            ControllerData.pointerCurrentRaycast = FindFirstRaycast(m_RaycastResultCache);
            _guiRaycastHit = (ControllerData.pointerCurrentRaycast.gameObject != null ? true : false);
            m_RaycastResultCache.Clear();

            return(ControllerData);
        }