/// <summary> /// Attempts to click the pointer /// </summary> /// <param name="pointer">Pointer to attempt to click</param> /// <returns>True if attempt successfull. False otherwise.</returns> protected virtual bool AttemptClick(UIPointer pointer) { if (pointer.pointerEventData.pointerPress) { if (!ValidElement(pointer, pointer.pointerEventData.pointerPress)) { pointer.pointerEventData.pointerPress = null; return(true); } if (pointer.pointerEventData.eligibleForClick) { if (!IsHovering(pointer)) { ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerPress, pointer.pointerEventData, ExecuteEvents.pointerUpHandler); pointer.pointerEventData.pointerPress = null; } } else { ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerPress, pointer.pointerEventData, ExecuteEvents.pointerClickHandler); ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerPress, pointer.pointerEventData, ExecuteEvents.pointerUpHandler); pointer.pointerEventData.pointerPress = null; } return(true); } return(false); }
/// <summary> /// Clicks the pointer when click stops /// </summary> /// <param name="pointer">Pointer to click</param> /// <param name="results">Raycast results</param> protected virtual void ClickOnUp(UIPointer pointer, List <RaycastResult> results) { pointer.pointerEventData.eligibleForClick = pointer.Click; if (!AttemptClick(pointer)) { IsEligibleClick(pointer, results); } }
/// <summary> /// Clicks the pointer when click starts /// </summary> /// <param name="pointer">Pointer to click</param> /// <param name="results">Raycast results</param> protected virtual void ClickOnDown(UIPointer pointer, List <RaycastResult> results, bool forceClick = false) { pointer.pointerEventData.eligibleForClick = (forceClick ? true : pointer.Click); if (IsEligibleClick(pointer, results)) { pointer.pointerEventData.eligibleForClick = false; AttemptClick(pointer); } }
/// <summary> /// Attempts to set hover properties if the pointer is hovering over an object /// </summary> /// <param name="pointer">Pointer to update</param> /// <param name="results">Raycast results</param> protected virtual void Hover(UIPointer pointer, List <RaycastResult> results) { if (pointer.pointerEventData.pointerEnter) { if (!ValidElement(pointer, pointer.pointerEventData.pointerEnter)) { pointer.pointerEventData.pointerEnter = null; return; } if (NoValidCollision(pointer, results)) { ExecuteEvents.ExecuteHierarchy(pointer.pointerEventData.pointerEnter, pointer.pointerEventData, ExecuteEvents.pointerExitHandler); pointer.pointerEventData.hovered.Remove(pointer.pointerEventData.pointerEnter); pointer.pointerEventData.pointerEnter = null; } } else { foreach (var result in results) { if (!ValidElement(pointer, result.gameObject)) { continue; } var target = ExecuteEvents.ExecuteHierarchy(result.gameObject, pointer.pointerEventData, ExecuteEvents.pointerEnterHandler); if (target != null) { var selectable = target.GetComponent <Selectable>(); if (selectable) { var noNavigation = new Navigation(); noNavigation.mode = Navigation.Mode.None; selectable.navigation = noNavigation; } pointer.HoveredElement = target; pointer.pointerEventData.pointerCurrentRaycast = result; pointer.pointerEventData.pointerEnter = target; pointer.pointerEventData.hovered.Add(pointer.pointerEventData.pointerEnter); break; } else { pointer.HoveredElement = result.gameObject; } } if (pointer.HoveredElement && results.Count == 0) { pointer.HoveredElement = null; } } }
/// <summary> /// Determines whether the pointer is hovering over an object /// </summary> /// <param name="pointer">Pointer to check</param> /// <returns>True if pointer is hovering over an object. False otherwise</returns> protected virtual bool IsHovering(UIPointer pointer) { foreach (var hoveredObject in pointer.pointerEventData.hovered) { if (pointer.pointerEventData.pointerEnter && hoveredObject && CheckTransformTree(hoveredObject.transform, pointer.pointerEventData.pointerEnter.transform)) { return(true); } } return(false); }
/// <summary> /// Clicks the pointer /// </summary> /// <param name="pointer">Pointer to click</param> /// <param name="results">Raycast results</param> protected virtual void Click(UIPointer pointer, List <RaycastResult> results) { switch (pointer.clickMethod) { case UIPointer.ClickMethods.ClickOnButtonUp: ClickOnUp(pointer, results); break; case UIPointer.ClickMethods.ClickOnButtonDown: ClickOnDown(pointer, results); break; } }
/// <summary> /// Gets raycast resutls from the specified pointer /// </summary> /// <param name="pointer">pointer to get results from</param> /// <returns>Raycast results</returns> protected virtual List <RaycastResult> CheckRaycasts(UIPointer pointer) { // Pear_GraphicRaycaster uses worldPosition and worldNormal // to raycast var raycastResult = new RaycastResult(); raycastResult.worldPosition = pointer.GetOriginPosition(); raycastResult.worldNormal = pointer.GetOriginForward(); pointer.pointerEventData.pointerCurrentRaycast = raycastResult; List <RaycastResult> raycasts = new List <RaycastResult>(); eventSystem.RaycastAll(pointer.pointerEventData, raycasts); return(raycasts); }
/// <summary> /// Process each pointer /// </summary> public override void Process() { for (int i = 0; i < pointers.Count; i++) { UIPointer pointer = pointers[i]; if (pointer.gameObject.activeInHierarchy && pointer.enabled) { List <RaycastResult> results = new List <RaycastResult>(); if (pointer.IsActive) { results = CheckRaycasts(pointer); } //Process events Hover(pointer, results); Click(pointer, results); } } }
/// <summary> /// Determines if the pointer is eligible for a click /// </summary> /// <param name="pointer">Pointer to check</param> /// <param name="results">Raycast results</param> /// <returns>True if pointer is eligible. False otherwise.</returns> protected virtual bool IsEligibleClick(UIPointer pointer, List <RaycastResult> results) { if (pointer.pointerEventData.eligibleForClick) { foreach (var result in results) { if (!ValidElement(pointer, result.gameObject)) { continue; } var target = ExecuteEvents.ExecuteHierarchy(result.gameObject, pointer.pointerEventData, ExecuteEvents.pointerDownHandler); if (target != null) { pointer.pointerEventData.pressPosition = pointer.pointerEventData.position; pointer.pointerEventData.pointerPressRaycast = result; pointer.pointerEventData.pointerPress = target; return(true); } } } return(false); }
/// <summary> /// Checks whether there was a valid collision /// </summary> /// <param name="pointer">Pointer that raycasted</param> /// <param name="results">Results from raycast</param> /// <returns></returns> protected virtual bool NoValidCollision(UIPointer pointer, List <RaycastResult> results) { return(results.Count == 0 || !CheckTransformTree(results[0].gameObject.transform, pointer.pointerEventData.pointerEnter.transform)); }
/// <summary> /// Checks whether the GameObject is a valid element /// </summary> /// <param name="pointer">Pointer used during determination</param> /// <param name="obj">Object to check</param> /// <returns>True if object is valid. False otherwise.</returns> protected virtual bool ValidElement(UIPointer pointer, GameObject obj) { var canvasCheck = obj.GetComponentInParent <Canvas>(); return(pointer.IsValidElement(obj) && (canvasCheck && canvasCheck.enabled ? true : false)); }