Adventures in Tooltip-land

Alright. That was hard work lol. I tried to extend the TooltipSpawner class via a new class called PickupTooltipSpawner, but was hampered big-time as I’m using 2D non-GUI thingies, so I won’t get OnPointerEnter calls… But I persevered, and after much pain and suffering, taking some inspiration from the (free!) Simple Tooltip asset that Steve mentioned on the other thread, I got there.

The chest in the below GIF uses Simple Tooltip and the Pickups use Sam’s code with my TooltipSpawner on top… I think I learned a lot, took way longer than I would have liked though :laughing:
CoV_tooltips_02

PS. To get the tooltips to not get in the way of my mouse clicks, I unset ‘Raycast Target’ on the Image component on the ItemTooltip prefab. And lowered the alpha on the Image Colour property.

3 Likes

Well done!

I think the issue isn’t that IPointerEnterHandler isn’t working (it should work on any GameObject) it’s that our implementation searches for a canvas in the parent of the GameObject that the IPointerEnterHandler is attached to.

    void IPointerEnterHandler.OnPointerEnter(PointerEventData eventData)
    {
        var parentCanvas = GetComponentInParent<Canvas>();  //Only UI will have a parentCanvas

        if (tooltip && !CanCreateTooltip())
        {
            ClearTooltip();
        }

        if (!tooltip && CanCreateTooltip())
        {
            tooltip = Instantiate(tooltipPrefab, parentCanvas.transform);
        }

        if (tooltip)
        {
            UpdateTooltip(tooltip);
            PositionTooltip();
        }
    }

We get the ParentCanvas because we need a canvas parent to instantiate the tooltip onto (without a canvas, UI is invisible)

I’m thinking adding this line immediately after the GetComponentInParent call might fix this:

if(!parentCanvas) parentCanvas = FindObjectOfType<Canvas>();

This would create a fallback by locating the first canvas within the scene to use to display the tooltip.

1 Like

Hmm… that didn’t seem to work… more investigation is needed. Thankfully, you were able to get them working with the other utility.

1 Like

Thanks, Brian. Yeah I spent quite a few hours on this yesterday. My first thought was that the ‘PlayerController’ script was interfering - certainly it does with mouse clicks, so I consolidated all my mouse control logic there last week.

OnMouseOver and OnMouseExit definitely work though - this is my working but slightly hacky implementation of a PickupTooltipSpawner. Feedback greatly appreciated :slight_smile:

Edit: I know I should definitely cache that Stats Canvas Find.

/// <summary>
/// To be placed on a Pickup Spawner.
/// </summary>
[RequireComponent(typeof(IItemHolder))]
public class PickupTooltipSpawner : TooltipSpawner
{
    bool showingToolTip;
    GameObject instancedToolTip;

    private EventSystem eventSystem;

    private bool isUIObject = false;
    private bool showing = false;

    public void Awake()
    {
        eventSystem = FindObjectOfType<EventSystem>();

        if (GetComponent<RectTransform>())
            isUIObject = true;
    }

    private void OnMouseOver()
    {
        if (isUIObject)
            return;

        if (eventSystem)
        {
            if (eventSystem.IsPointerOverGameObject())
            {
                Activate(gameObject);
                return;
            }
        }
        Activate(gameObject);
    }

    private void OnMouseExit()
    {
        if (isUIObject)
            return;
        DeactivateTooltip();
    }

    public void OnMouseDown()
    {
        DeactivateTooltip();
    }

    public override bool CanCreateTooltip()
    {
        return true;
    }

    public override void UpdateTooltip(GameObject tooltip)
    {
        // Not working implementation code lives here
    }

    public void Activate(GameObject clickablePickup)
    {
        if (showingToolTip)
        {
            return;
        }

        instancedToolTip = Instantiate(tooltipPrefab, GameObject.Find("Stats Canvas").transform);
        var click = instancedToolTip.GetComponent<ItemTooltip>();
        showingToolTip = true;

        var pickup = clickablePickup.GetComponent<GameDevTV.Inventories.Pickup>();
        var item = pickup.GetItem();
        click.Setup(InventoryItem.GetFromID(item.GetItemID()));
    }

    public void DeactivateTooltip()
    {
        Destroy(instancedToolTip);
        showingToolTip = false;
    }

    public void OnDestroy()
    {
        DeactivateTooltip();
    }
}

Privacy & Terms