下面展示一下上一篇说的两种实现方式打包文件在不同分辨率下的效果
1.WorldToScreenPoint
1920 * 1080
800 * 600
2.WorldToViewportPoint
1920 * 1080
800 * 600
总结
可以看到四种情况全部都显示正确,我们再看一下原来的代码
public Vector3 GetScreenPosition(GameObject target)
{
Vector3 viewportPos = Camera.main.WorldToViewportPoint(target.transform.position);
RectTransform canvasRtm = parentCanvas.GetComponent<RectTransform>();
Vector2 uguiPos = Vector2.zero;
uguiPos.x = (viewportPos.x - 0.5f) * canvasRtm.sizeDelta.x;
uguiPos.y = (viewportPos.y - 0.5f) * canvasRtm.sizeDelta.y;
return uguiPos;
}
public Vector3 GetScreenPosition(GameObject target)
{
RectTransform canvasRtm = parentCanvas.GetComponent<RectTransform>();
float width = canvasRtm.sizeDelta.x;
float height = canvasRtm.sizeDelta.y;
Vector3 pos = Camera.main.WorldToScreenPoint(target.transform.position);
pos.x *= width / Screen.width;
pos.y *= height / Screen.height;
pos.x -= width * 0.5f;
pos.y -= height * 0.5f;
return pos;
}
我们分析可知
WorldToScreenPoint获取的是基于参考分辨率得到的坐标,也就是我们最初设计的1920 * 1080,我们在使用的时候,要根据当前分辨率和标准分辨率的比值,对的到的坐标进行转换,得到当前分辨率下的坐标。
WorldToViewPoint获取的是基于当前可视窗口下的坐标的比例,不受参考分辨率的影响,得到的是(0-1)之间的数值,所以我们只要与当前分辨率相乘就可以得到我们需要的结果。
当然由于UI坐标是以中心点作为原点,所以我们需要对得到的结果做半个屏幕的偏移,这样就可以获得我们最终需要的UI坐标
下面说一下第一次做的时候我犯的错误,就是下面这句话
RectTransform canvasRtm = parentCanvas.GetComponent<RectTransform>();
如果我们不使用这句话获取真实分辨率 ,那么我们就只能通过基础分辨率、Canvas的参考分辨率和Canvas的Match三个数值进行计算来获取我们的真实分辨率。所以很多时候我计算出了错误的结果,最终根据多次测试结果才得到了正确的比例公式(PS:而且在Editor和exe中转换的公式还不一样!!!),小伙伴们以后有这种需求,只需要设置一个全屏填充的Canvas,也就是我上面写的parentCanvas,然后通过获取这个Canvas的RectTransform就可以获取最后的真实分辨率尺寸,坐标转换模块到此结束,贴一下前几篇文章,方便大家阅读。