首先要明白一个概念
UGUI的坐标系 ,是以屏幕中心为原点 就是说 什么都不动 一上来设置0 0点 在最正中间
而Screen坐标系,以屏幕左下角为原点
比如你有一个3d物体 你想给他加一个血条 并且这个血条在ugui里的层级特别深 那么可以这么整
var screenPoint = mainCamera.WorldToScreenPoint(this.hero.transform.position);
var localPosition = new Vector2();
UnityEngine.RectTransformUtility.ScreenPointToLocalPointInRectangle(this.blood.transform.parent as RectTransform,
screenPoint, canvas.worldCamera, out localPosition);
this.blood.transform.localPosition = localPosition;
Camera.WorldToScreenPoint
这个是把你的position 也就是 世界坐标系 转换为屏幕坐标
然后调用 ScreenPointToLocalPointInRectangle 就是 localPosition 坐标了
三个坐标系的转换 可以参考下这个图
图片来源 https://zhuanlan.zhihu.com/p/93813556
有两个类有 WorldToScreenPoint 方法
Camera 类里有这个方法 返回的是 Vector3
RectTransformUtility 里返回的是 Vector2
如果以前你接触过h5游戏引擎 laya egret 等 那么一定对 globalToLocal 或者 localToGlobal 方法非常熟悉
那么下面的满足你
记住 摄像头是 ui摄像头也就是canvas用的那个
Vector2 localToGlobal(Transform transform , Vector2 vec2)
{
var screenPoint = RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, transform.position);
var GlobalPosition = new Vector2();
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvas.transform as RectTransform,
screenPoint, canvas.worldCamera, out GlobalPosition);
return GlobalPosition + vec2;
}
Vector2 globalToLocal(Transform transform , Vector2 vec2 )
{
var screenPoint = RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, canvas.transform.position);
var localPosition = new Vector2();
UnityEngine.RectTransformUtility.ScreenPointToLocalPointInRectangle(transform as RectTransform,
screenPoint, canvas.worldCamera, out localPosition);
return localPosition + vec2;
}
//转换到任意Transform
Vector2 localToRectTransform(Transform transform, Vector2 v, Transform target)
{
var screenPoint = RectTransformUtility.WorldToScreenPoint(canvas.worldCamera, transform.position);
var res = new Vector2();
RectTransformUtility.ScreenPointToLocalPointInRectangle(target as RectTransform, screenPoint,
canvas.worldCamera, out res);
return res + v;
}
顺便一提
img9放到canvas的根上 并设置为以左下角为原点
这时候
this.img9.transform.localPosition = new Vector2(0, 0);
那么图片还是在canvas的正中间
因为 localPosition 不在乎你设置的 Anchors 在哪
如果你希望和编辑器里显示的效果一样 那么需要用anchoredPosition
this.img9.rectTransform.anchoredPosition = new Vector2(0, 0);
那么img9就乖乖到屏幕左下角去了