Unity UI的transform,recttransform,position的相互转换

学习中遇到一些坑,记录一下,因为RectTransform坐标转换第一次遇到真的头疼

1,首先要理解RectTransform是Transform的子类,而所有的UI组件,在代码中获取的transform.position实际上都是rectTransform.anchoredPosition,也就是说,新建一个空物体,加入Image、Text等组件后,这个物体只有在Canvas下,才能显示出来,它的Transform组件自动被替换为RectTransform。

2, rectTransform.anchoredPosition是该UI物体的Pivot对应它的锚点的坐标,如果锚点为一个点,就比较好理解,如果锚点是父物体Panel或者canvas的四个角,那还牵涉到unity内部的一些计算,具体这里不深入研究。

3, 那么如果我们需要一个一个UI的世界坐标,来进行一些操作,应该怎么做?

假设:(1) 目标ui在canvas下,canvas的模式为camera,camera为专门的UIcamera。此时UI和canvas画布是可以在scene中看到的,作为游戏物体的一部分出现。

(2)我们还有一个maincamera来拍摄渲染整个游戏场景

(3) 我们需要一个linerenderer来从ui指向场景中某个物体。

那么场景中的物体坐标很容易得到,我们需要的就是UI的坐标。

第一步:将UI的position转换为屏幕坐标

unity提供了一个方法RectTransformUtility.WorldToScreenPoint(Camera camera,Vector3 point),我们将UI的transform.position也就是实际上的rectTransform.anchoredPosition传进point中,将UIcamera传进camera中,就可以得到这个ui的屏幕坐标。

RectTransformUtility.WorldToScreenPoint(UIcamera,transform.position)

第二步,将屏幕坐标转换为世界坐标

这时我们所选用的摄像机就由UIcamera换成Camera.main,因为canvas在任何位置都不影响UIcamera渲染它,而我们游戏世界是由maincamera来渲染的,所以此时摄像机应该使用mainCamera。

unity同样提供了一个方法Camera.ScreenToWorldPoint(Vector3 point)来处理这个问题,需要注意的是,之前RectTransformUtility.WorldToScreenPoint方法的返回值是一个Vector2,而这个方法的入参是vector3,需要处理一下Z轴,否则返回值永远是一个(0,0,0)的三维向量。

 //主相机到2D界面的距离
            float distance = Mathf.Abs(GameObject.Find("BackGroundCanvas").GetComponent<Canvas>().planeDistance) ;
            // return GameObject.Find("UICamera").GetComponent<Camera>().ScreenToWorldPoint(new Vector3(mousPos.x, mousPos.y, distance));
            return camera.ScreenToWorldPoint(new Vector3(mousPos.x, mousPos.y, distance));

此处我的项目是一个2D项目,暂时的Z轴使用背景层canvas的planedistance,方法外部再进行-1,以保证生成的linerenderer在背景层上显示。

第二个坑: UI预制体创建时如果没有指定父物体为canvas,就会导致位置、大小出现问题

因为canvas的camera模式在渲染时是进行了缩放的:如果没有缩放,那么比如canvas的planedistance设定为100,那么在摄像机中看到的canvas就会非常小了。如果没有指定父物体为canvas或其子物体,就会导致创建出来的UI物体巨大,位置也因为LocalPosition等变换问题出现奇怪的偏移

总结:折腾了一天才处理明白,我的处理方法应该也不是最好的,因为感觉堆2D项目中Z轴、DEPTH的理解还不够清晰。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Unity中,RectTransformTransform都可以用来表示游戏对象的位置、旋转和缩放。RectTransform主要用于UI元素在画布上的定位和排版,而Transform则用于3D场景中游戏对象的定位和排版。它们的位置转换可以通过以下方式实现: 1. 从RectTransformTransform转换 要将RectTransform的位置转换Transform的位置,需要使用RectTransform的anchoredPosition属性和anchorMin、anchorMax属性,以及Canvas的scaleFactor属性。具体步骤如下: - 获取RectTransform的anchoredPosition属性,并将其转换为Canvas坐标系下的位置。 - 获取RectTransform的anchorMin和anchorMax属性,计算出UI元素的宽度和高度。 - 获取Canvas的scaleFactor属性,计算出Canvas坐标系和世界坐标系之间的缩放比例。 - 将Canvas坐标系下的位置转换为世界坐标系下的位置,即可得到Transform的位置。 2. 从TransformRectTransform转换 要将Transform的位置转换RectTransform的位置,需要使用Canvas的RenderMode属性和RectTransform的anchoredPosition属性。具体步骤如下: - 获取Canvas的RenderMode属性,判断Canvas的渲染模式是Screen Space还是World Space。 - 如果Canvas的渲染模式是Screen Space,直接将Transform的位置转换为屏幕坐标系下的位置。 - 如果Canvas的渲染模式是World Space,需要将Transform的位置转换为Canvas坐标系下的位置,然后再转换RectTransform的anchoredPosition属性。具体步骤同从RectTransformTransform转换。 需要注意的是,RectTransformTransform的坐标系不同,转换时需要注意坐标系的转换。此外,RectTransformTransform的旋转和缩放也需要进行转换。可以使用Transform的localRotation和localScale属性,或使用RectTransform的rotation和sizeDelta属性来实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值