屏幕自适应,防止pop弹窗超出规定边界

/// <summary>
/// 窗口组件自适应
/// parentRect作为窗口边界,规定允许边界内对齐移动
/// targetRect最为对齐目标,锚点分为上下对齐两种方式,根据parentRect上下边界自动计算
/// </summary>
public class WindowAdapter : MonoBehaviour
{
    [Header("父物体")]
    [SerializeField]
    private RectTransform parentRect;

    [Header("对齐锚点")]
    [SerializeField]
    private AdaptionPivot adaptionPivot = AdaptionPivot.Bottom;

    private RectTransform rectTrans
    {
        get { return transform as RectTransform;}
    }

    [SerializeField]
    private AdaptionType adaptionType = AdaptionType.Both;

    [SerializeField] private Vector2 alignOffset = Vector2.zero;


    private Vector2 targetPos = Vector2.zero;


    #region  private
    private void Awake()
    {
        rectTrans.anchorMin = Vector2.zero;
        rectTrans.anchorMax = Vector2.zero;

        switch (adaptionPivot)
        {
             case AdaptionPivot.Top:
                 rectTrans.pivot = new Vector2(0.5f,1f);
                 break;
            case AdaptionPivot.Middle:
                rectTrans.pivot = new Vector2(0.5f,0.5f);  
                break;
            case AdaptionPivot.Bottom:
                rectTrans.pivot = new Vector2(0.5f,0f);
                break;
        }
    }
    
    private void Adaption()
    {
        switch (adaptionType)
        {
            case AdaptionType.Horizontal:
                HorAdaption();
                break;
            case AdaptionType.Vertical:
                VerAdaption();
                break;
            default:
                HorAdaption();
                VerAdaption();
                break;
        }
    }

    private void HorAdaption()
    {
        float rectHalf = rectTrans.rect.width / 2;
        float currentPosX = targetPos.x + rectHalf + alignOffset.x;
        if (currentPosX > parentRect.rect.width)
        {
            float x = parentRect.rect.width - rectHalf;
            rectTrans.anchoredPosition = new Vector2(x,rectTrans.anchoredPosition.y);
        }else if (targetPos.x + alignOffset.x - rectHalf < 0)
        {
            rectTrans.anchoredPosition = new Vector2(rectHalf,rectTrans.anchoredPosition.y);
        }
        else
        {
            rectTrans.anchoredPosition = new Vector2(targetPos.x + alignOffset.x,rectTrans.anchoredPosition.y);
        }
    }

    private void VerAdaption()
    {
        float topAnc = 0;
        float bottomAnc = 0;
        if (rectTrans.localScale.y == 1)
        {
            topAnc = rectTrans.rect.height * (1 - rectTrans.pivot.y);
            bottomAnc = rectTrans.rect.height * rectTrans.pivot.y;
        }
        else
        {
            topAnc = rectTrans.rect.height * rectTrans.pivot.y;
            bottomAnc = rectTrans.rect.height * (1 - rectTrans.pivot.y);
        }
  
        float topPosy = targetPos.y + topAnc + alignOffset.y;
        float bottomPosy = targetPos.y - bottomAnc + alignOffset.y;
        
        if (topPosy > parentRect.rect.height)
        {
            float y = parentRect.rect.height - topAnc;
            rectTrans.anchoredPosition = new Vector2(rectTrans.anchoredPosition.x,y);
        }else if (bottomPosy < 0)
        {
            rectTrans.anchoredPosition = new Vector2(rectTrans.anchoredPosition.x,bottomAnc);
        }
        else
        {
            rectTrans.anchoredPosition = new Vector2(rectTrans.anchoredPosition.x,targetPos.y + alignOffset.y);
        }
    }
    
    #endregion
    
    #region  public

    /// <summary>
    /// 自动对齐
    /// </summary>
    public void AlignWithTarget(RectTransform targetRect)
    {
        targetPos = Vector2.zero;

        if (Camera.main == null || parentRect == null || targetRect == null)
        {
            Debug.LogError("GetAnchorPos error");
            return; 
        }
        var screenPoint = RectTransformUtility.WorldToScreenPoint(Global.UICamera, targetRect.position);
        RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRect, screenPoint, Global.UICamera, out targetPos);

        Adaption();
    }

    #endregion
    
}

public enum AdaptionType
{
    Both = 0,
    Horizontal = 1,
    Vertical = 2,
}

public enum AdaptionPivot
{
    Top = 0,
    Middle = 1,
    Bottom = 2,
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值