Unity ScrollRect控件,将Content中任意元素定位到viewport中心的方法

参考:

ugui max min auchor解释

localPosition与anchoredPosition的转化关系

Unity UGUI 原理篇(三):RectTransform

RectTransform中localPosition与anchoredPosition的区别

UGUI在两个UI间坐标转换


这个需求是做一个小游戏项目中,需要将玩家退出游戏时的关卡保存,在重新加载的过程中,在选关界面的中心自动定位到该关卡。

一开始我的思路也很简单:获取该元素的世界坐标,将使用viewport(视口)的中心坐标减去该坐标,再调用Dotween的DoMoveY()方法,将content平移到该点。

但过程中出了些意外,原因是我的关卡都是通过 Instantiate(Prefab)后填充到Content中,但由于我将自动定位的方法直接写到了awake()中,导致每次都拿到了Prefab的世界坐标;而不是生成后的最新坐标,此时我以为我之前的思路出了问题,于是开始寻找其他坐标转换的方法。

事实上最开始的方法是完全可行且非常简洁的,在重新弄明白localPosition与anchoredPosition的区别后,我想到了新的解决办法:

因为当子物体的anchor与父物体的pivot坐标重合时anchoredPosition3D与localPosition相等,而Content的父物体是ViewPort ,所以我需要将content下的元素父物体改为Viewport,这样两者的anchoredPosition才在同一坐标系,之后的思路和前面一致,只不过操作对象由Tranform.position改为了anchoredPosition。

实际检测以上两种方法都可行,一下是我的代码,实际上项目中我删除了一些控件,代码中的ScrollRect你可以视为原本的viewport控件,而Viewport你可以视为Content( \( ̄▽ ̄)/)

//世界坐标移动的方法
 void Test(GameObject selected)
    {

        var target = selected.GetComponent<RectTransform>();

        Vector3 sCenter = scrollRect.transform.position;
        Debug.Log("Center Pos: " + sCenter);

        Vector3 itemCenterPos = target.transform.position;
        Debug.Log("Item Center Pos: " + itemCenterPos);

        Vector3 difference = sCenter - itemCenterPos;
        Vector3 newPos = viewport.transform.position + difference;

        viewport.transform.DOMoveY(newPos.y, 1f);
    }
//anchoredPosition的移动方法
    void Test2(GameObject selected)
    {
        var target = selected.GetComponent<RectTransform>();
        Text text = target.transform.GetChild(0).GetComponent<Text>();
        Debug.Log("当前物体ID" + text.text);
        Debug.Log("转换前物体坐标" + target.anchoredPosition);
        var screenPoint = RectTransformUtility.WorldToScreenPoint(camera, target.transform.position);
        //将物体作为scollrect的子物体
        Vector2 rTarget;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(scrollRect, screenPoint, camera, out  rTarget);

        Debug.Log("转换后物体坐标" + rTarget);
        Vector2 sCenter = scrollRect.rect.center;
        Debug.Log("scrollRect中心坐标" + sCenter);

        Vector2 distance = sCenter - rTarget;

        Vector2 newPos = viewport.anchoredPosition + distance;

        viewport.DOAnchorPosY (newPos.y, 2f);

    }

效果图:

在这里插入图片描述

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值