/// <summary>Displays the tooltip.</summary> /// <remarks> /// This method first waits a couple frames before sizing and positioning the tooltip. /// This is necessary in order to get an accurate preferredWidth property of the dynamic text field. /// </remarks> public IEnumerator Show(TooltipTrigger trigger) { if (trigger.tooltipStyle == null) { Debug.LogWarning("TooltipTrigger \"" + trigger.name + "\" has no associated TooltipStyle. Cannot show tooltip."); yield break; } Tooltip tooltip = trigger.Tooltip; Image tooltipBkgImg = tooltip.BackgroundImage; // Move the tooltip to the No Angle container if it should never be rotated. if (tooltip.NeverRotate) { tooltip.GameObject.transform.SetParent(TooltipContainerNoAngle.transform, false); } // Replace dynamic image placeholders with the correct images. if (trigger.dynamicImageFields != null) { for (int i = 0; i < trigger.dynamicImageFields.Count; i++) { for (int j = 0; j < tooltip.ImageFields.Count; j++) { if (tooltip.ImageFields[j].Name == trigger.dynamicImageFields[i].name) { if (trigger.dynamicImageFields[i].replacementSprite == null) { tooltip.ImageFields[j].Image.sprite = tooltip.ImageFields[j].Original; } else { tooltip.ImageFields[j].Image.sprite = trigger.dynamicImageFields[i].replacementSprite; } } } } } // Toggle dynamic sections on or off. if (trigger.dynamicSectionFields != null) { for (int i = 0; i < trigger.dynamicSectionFields.Count; i++) { for (int j = 0; j < tooltip.SectionFields.Count; j++) { if (tooltip.SectionFields[j].Name == trigger.dynamicSectionFields[i].name) { tooltip.SectionFields[j].GameObject.SetActive(trigger.dynamicSectionFields[i].isOn); } } } } // Wait for 2 frames so we get an accurate PreferredWidth on the Text component. yield return(WaitFor.Frames(2)); // Get the parent canvas for this tooltip trigger. GuiCanvas = trigger.GetComponentInParent <Canvas>(); // If no parent canvas is found for the trigger object, use the main canvas. if (GuiCanvas == null) { GuiCanvas = CanvasHelper.GetRootCanvas(); } // Parent the tooltip container under the correct canvas. TooltipContainer.transform.SetParent(GuiCanvas.transform, false); // Set the position of the tooltip. tooltip.SetPosition(trigger, GuiCanvas, guiCamera); // Set the tint color of the tooltip panel and tips. tooltipBkgImg.color = trigger.backgroundTint; // If this is a blocking tooltip, assign it as such. if (tooltip.IsBlocking) { BlockingTooltip = tooltip; } // Display the tooltip. tooltip.Display(fadeDuration); }
/// <summary>Sets the position of the tooltip container.</summary> public static void SetPosition(this Tooltip tooltip, TooltipTrigger trigger, Canvas canvas, Camera camera) { Vector3[] triggerCorners = new Vector3[4]; RectTransform triggerRectTrans = trigger.gameObject.GetComponent <RectTransform>(); if (triggerRectTrans != null) { triggerRectTrans.GetWorldCorners(triggerCorners); } else { // We're not using a trigger from a Canvas, so that means it's a regular world space game object. // So, find the collider bounds of the object and use that for the four corners. Collider coll = trigger.GetComponent <Collider>(); Vector3 center = coll.bounds.center; Vector3 extents = coll.bounds.extents; Vector3 frontBottomLeftCorner = new Vector3(center.x - extents.x, center.y - extents.y, center.z - extents.z); Vector3 frontTopLeftCorner = new Vector3(center.x - extents.x, center.y + extents.y, center.z - extents.z); Vector3 frontTopRightCorner = new Vector3(center.x + extents.x, center.y + extents.y, center.z - extents.z); Vector3 frontBottomRightCorner = new Vector3(center.x + extents.x, center.y - extents.y, center.z - extents.z); triggerCorners[0] = camera.WorldToScreenPoint(frontBottomLeftCorner); triggerCorners[1] = camera.WorldToScreenPoint(frontTopLeftCorner); triggerCorners[2] = camera.WorldToScreenPoint(frontTopRightCorner); triggerCorners[3] = camera.WorldToScreenPoint(frontBottomRightCorner); } // Set the initial tooltip position. tooltip.SetPosition(trigger.tipPosition, trigger.tooltipStyle, triggerCorners, tooltip.BackgroundImage, tooltip.RectTransform, canvas, camera); // If overflow protection is disabled, exit. if (!TooltipManager.Instance.overflowProtection) { return; } // Check for overflow. Vector3[] tooltipCorners = new Vector3[4]; tooltip.RectTransform.GetWorldCorners(tooltipCorners); if (canvas.renderMode == RenderMode.ScreenSpaceCamera || canvas.renderMode == RenderMode.WorldSpace) { for (int i = 0; i < tooltipCorners.Length; i++) { tooltipCorners[i] = RectTransformUtility.WorldToScreenPoint(camera, tooltipCorners[i]); } } else if (canvas.renderMode == RenderMode.ScreenSpaceOverlay) { for (int i = 0; i < tooltipCorners.Length; i++) { tooltipCorners[i] = RectTransformUtility.WorldToScreenPoint(null, tooltipCorners[i]); } } Rect screenRect = new Rect(0, 0, Screen.width, Screen.height); TooltipOverflow overflow = new TooltipOverflow { BottomLeftCorner = !screenRect.Contains(tooltipCorners[0]), // is the tooltip out of bounds on the Bottom Left? TopLeftCorner = !screenRect.Contains(tooltipCorners[1]), // is the tooltip out of bounds on the Top Left? TopRightCorner = !screenRect.Contains(tooltipCorners[2]), // is the tooltip out of bounds on the Top Right? BottomRightCorner = !screenRect.Contains(tooltipCorners[3]) // is the tooltip out of bounds on the Bottom Right? }; // If the tooltip overflows its boundary rectange, reposition it. if (overflow.IsAny) { tooltip.SetPosition(overflow.SuggestNewPosition(trigger.tipPosition), trigger.tooltipStyle, triggerCorners, tooltip.BackgroundImage, tooltip.RectTransform, canvas, camera); } }