今天一个同事问我怎么样获取UI在Canvas下的2D坐标。我查了一下API,其实很简单。如下图所示,UI比较复杂了子节点会很多,假设我想获取某个子的子节点的2D坐标。
首先我们要搞清楚 transform.postion 和 rectTransform.anchoredPosition 这两个坐标是完全不一样的。前面的是3D坐标,后面的是2D在Rect里的坐标,并且还是相对坐标,那么节点深了坐标就更不好换算了。
1 2 3 4 5 6 7 8 9 10 11 |
public Canvas canvas; void Start(){ Vector2 pos; if(RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, transform.position, canvas.camera, out pos)){ Debug.Log(pos); } } |
所以上述代码就是用UI元素的世界坐标和canvas的RectTrasform再加上UI摄像机,换算出元素在Canvas的2D坐标。
最后在想需要赋值的UI 用 rectTransform.anchoredPosition = pos 就可以了。。
今天有朋友问我,怎么通过鼠标的坐标在屏幕上移动来更新UI的显示位置。代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using UnityEngine; using System.Collections; public class NewBehaviourScript : MonoBehaviour { Canvas canvas; RectTransform rectTransform; // Use this for initialization void Start () { rectTransform = transform as RectTransform; canvas = GameObject.Find("Canvas").GetComponent<Canvas>(); } // Update is called once per frame void Update () { Vector2 pos; if(RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform, Input.mousePosition, canvas.worldCamera, out pos)){ rectTransform.anchoredPosition = pos; } } } |
- 本文固定链接: https://www.xuanyusong.com/archives/3476
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!
大神,我遇到一个棘手的问题。我正在开发一个用UI在世界画线的功能,想法是确定世界坐标的两个点,把它们转成屏幕坐标,然后用UGUI画线。但是当世界坐标的点超出屏幕太远,用RectTransformUtility.ScreenPointToWorldPointInRectangle方法转成屏幕坐标点的时候就会有问题,坐标值有时候甚至会上亿,请问有什么解决的办法吗?
可以用 RectTransform.GetWorldCorners来取世界坐标,最后比较全用transform.position来,这样单位就统一了
世界坐标我是知道的,就是世界坐标转到屏幕坐标的时候会出现问题,当画线的两个点中有一个点不在屏幕内,用RectTransformUtility.ScreenPointToWorldPointInRectangle方法转成屏幕坐标就会出现问题。
momo大神,有个问题想请教一下,:这个方法实现了效果,但是在相机旋转180之后,UI会出现在相机视野中,有什么解决方案吗?谢谢大神了。这个问题我查了很多方法都不行,希望大神不吝赐教!非常感谢!
这个问题我已经解决了,不用做回复了。
请问是怎么解决的呢,我也遇到这个问题了
雨松大神,这边在不修改描点,布局样式的情况下是正常可用的。但是只要改了描点或者布局,就无法正常使用了,因为anchoredPosition是相对坐标,而ScreenPointToLocalPointInRectangle这个方法只是转换出了canvas坐标。
修改为以下方法可正常布局
Vector3 worldP;
if(RectTransformUtility.ScreenPointToWorldPointInRectangle(
canvas.transform as RectTransform, Input.mousePosition, canvas.worldCamera, out worldP)){
rectTransform.position = worldP;
}
大神,按照你的代码,倒是能够显示鼠标所点的位置,但是,图片不能移动诶。求解决
如果锚点是自定义的会有问题,localposition好像更好!
对,这样不用考虑anchor的设置
怎么那么麻烦。现在的做法其实是获得当前容器下坐标的相对位置,如果层级比较深,那么要一层层换算相对位置?
我还是先看下api再发问
不用啊, 直接传父节点就可以换算了。
当看到大神这么写的时候,还纳闷一下,为啥应该填屏幕坐标的参数位置填世界坐标?经测试,当相机为canvas.camera的时候,世界坐标与屏幕坐标是相等的.canvas的范围就是摄像机的范围,同时左下角又是世界坐标系原点,也是屏幕坐标系原点.这样就不用将世界坐标转换成屏幕坐标了,加快了效率.
今天写的时候 rectTransform.anchoredPosition弄明白怎么给值了 但是实例化以后比例会变大
不会 。这个是相对坐标
大神今天写的时候又遇到问题了能帮忙写一下 一个Image从RectTrasfrom的(-100,100)移动到(100,-100)拜托啦!~
你这是UI上的点转换成世界点的吧 弄错了吧
搞错了,是第二参数,Vector2 你这边给的是 Vector3 不明这点
重载的方法吧。。
隐式类型转化.通过 .net reflactor 可以看到.Vector2源码. public static implicit operator Vector2(Vector3 v);
雨松 大神,有一点不明的地方,ScreenPointToLocalPointInRectangle ()里面的参数不应该是 RectTransform ,Vector2,camera,out 吗,怎么你这里的第三个参数可以是 Vector3 呢?
大神有没有大众点的的翻墙方法推荐下,直接发不方便可以给个链接或者度盘发个TXT,谢谢!~
astrill 我是花钱买的, 用起来挺稳定的。。
3q
朋友推荐雨松大神,看了以后感觉要学的实在太多了!~