[BUG] Position calculation problem in ItemViewSlotPanelToTooltip

WeiYiHua

Member
This version changed to calculate the offset in world space and there was a problem again.

After testing, calculating the lossyScale of slotRectTransform is a general solution, and the correct results can be obtained in Canvas's ScreenSpaceOverlay, ScreenSpaceCamera, and WorldSpace modes.

Code:
protected virtual void SetPanelPositionToSlot(RectTransform slotRectTransform, Vector2 anchorPosition, Vector2 pixelFixedOffset,
    Vector2 anchorRelativeOffset)
{
    var newAnchor = m_SetAnchorPosition ? anchorPosition : m_PanelToPlace.pivot;
    var newPosition = slotRectTransform.position;

    if (m_SetAnchorPosition) {
        m_PanelToPlace.anchorMax = newAnchor;
        m_PanelToPlace.anchorMin = newAnchor;
        m_PanelToPlace.pivot = newAnchor;
    }

    Vector2 positionOffset;
    if (m_Canvas.renderMode == RenderMode.ScreenSpaceCamera) {
        //When converting to world space the y gets inversed.
        var pixelOffset = new Vector2(pixelFixedOffset.x, -pixelFixedOffset.y);
        var worldRect = slotRectTransform.GetWorldRect(m_SlotRectCorners, pixelOffset);
        positionOffset = new Vector2(
            worldRect.size.x * anchorRelativeOffset.x,
            worldRect.size.y * anchorRelativeOffset.y);
    } else {
        var sizeDelta = slotRectTransform.sizeDelta;
        positionOffset = new Vector2(
            sizeDelta.x * m_AnchorRelativeOffset.x,
            sizeDelta.y * m_AnchorRelativeOffset.y);

        positionOffset = (positionOffset + pixelFixedOffset) * m_Canvas.scaleFactor;
    }

    newPosition += new Vector3(positionOffset.x, positionOffset.y);
    m_PanelToPlace.position = newPosition;
}

After the fix:
Code:
protected virtual void SetPanelPositionToSlot(RectTransform slotRectTransform, Vector2 anchorPosition, Vector2 pixelFixedOffset,
    Vector2 anchorRelativeOffset)
{
    var newAnchor = m_SetAnchorPosition ? anchorPosition : m_PanelToPlace.pivot;
    var newPosition = slotRectTransform.position;

    if (m_SetAnchorPosition) {
        m_PanelToPlace.anchorMax = newAnchor;
        m_PanelToPlace.anchorMin = newAnchor;
        m_PanelToPlace.pivot = newAnchor;
    }

    Vector2 positionOffset;
    var sizeDelta = slotRectTransform.sizeDelta;
    var lossyScale = slotRectTransform.lossyScale;
    sizeDelta *= anchorRelativeOffset;
    positionOffset = (sizeDelta + pixelFixedOffset) * lossyScale;

    newPosition += new Vector3(positionOffset.x, positionOffset.y);
    m_PanelToPlace.position = newPosition;
}

There is also a problem with the annotations of the OnItemSelected method and the OnItemClicked method.

By the way, if you want to use the mouse position instead of the slot position you can do so.
Code:
protected virtual void SetPanelPositionToSlot(RectTransform slotRectTransform, Vector2 anchorPosition, Vector2 pixelFixedOffset,
    Vector2 anchorRelativeOffset)
{
    var newAnchor = m_SetAnchorPosition ? anchorPosition : m_PanelToPlace.pivot;
    Vector3 newPosition;
    if (m_UsePointerPosition && m_PointerPosition.HasValue)
    {
        RectTransformUtility.ScreenPointToWorldPointInRectangle(slotRectTransform, m_PointerPosition.Value,
            m_Canvas.worldCamera, out var worldPointerPoint);
        newPosition = worldPointerPoint;
    }
    else
    {
        newPosition = slotRectTransform.position;
    }

    if (m_SetAnchorPosition) {
        m_PanelToPlace.anchorMax = newAnchor;
        m_PanelToPlace.anchorMin = newAnchor;
        m_PanelToPlace.pivot = newAnchor;
    }

    Vector2 positionOffset;
    var sizeDelta = slotRectTransform.sizeDelta;
    var lossyScale = slotRectTransform.lossyScale;
    sizeDelta *= anchorRelativeOffset;
    positionOffset = (sizeDelta + pixelFixedOffset) * lossyScale;

    newPosition += new Vector3(positionOffset.x, positionOffset.y);
    m_PanelToPlace.position = newPosition;
}
 
Top