最近在做新手引導,涉及到UI中查找子對象,並需要將子對象的坐標轉換到最外層Canvas中的坐標,看了很多人的帖子,其中雨松的帖子提供了一個轉換方式,但是並不能解決由於對子對象錨點,注冊點的自定義而造成的位置偏差。
通過研究發現,注冊點、錨點是ugui為了做自適應方案提供的,但在世界坐標系中,是沒有這些區分的,那么要解決上述ugui中子對象由於注冊點、錨點的不一致而造成的偏差,我們可以做如下轉換:
1 首先將子對象的世界坐標位置轉換成屏幕坐標位置
2 再將轉換后的屏幕坐標轉換到Canvas區域中的局部坐標
3 進行注冊點偏移矯正
/// <summary> /// 子對象坐標轉換到Canvas的局部坐標 /// </summary> /// <param name="current"></param> /// <param name="canvas"></param> /// <returns></returns> public static Vector2 TransformToCanvasLocalPosition(this Transform current, Canvas canvas) { var screenPos = canvas.worldCamera.WorldToScreenPoint(current.transform.position); Vector2 localPos; RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.GetComponent<RectTransform>(), screenPos, canvas.worldCamera, out localPos); return localPos; }
這是對Transform的一種擴展寫法
具體使用如下,target是你要參考坐標轉換的目標對象
var pos = target.transform.TransformToCanvasLocalPosition(MainUiCanvas); var rtr = target.GetComponent<RectTransform>();
//注冊點偏移矯正 pos.x = pos.x + (float)(rtr.rect.width * (rectTransform.pivot.x - rtr.pivot.x)); pos.y = pos.y + (float)(rtr.rect.height * (rectTransform.pivot.y - rtr.pivot.y));
rectTransform.anchoredPosition = pos;
至此 ,輸出的局部坐標位置,就是這個子對象在Canvas中的位置(錨點居中,注冊點居中)。這樣,你就可以輕松的創建一個新手引導的提示對象,放置於該局部坐標位置。
