Unity 不同父物体的UI坐标转换
众所周知,根据不同的参照物,Unity中有这许多的坐标系,那么在我们进行项目开发过程中,经常会牵扯到坐标系的转换来比较或者改变物体坐标位置,而我们用的最多的坐标系大致也就那么几种,世界坐标系,相对坐标系,屏幕坐标系,视口坐标系,GUI坐标系,下面我会简单介绍一下这几种坐标系,最后会着重讲今天的重点内容,屏幕坐标转UI坐标的操作。
最近在项目中碰到的问题,需要让参考UI和目标UI进行等高显示,但是这两种UI不在同一个父物体中,所以相对坐标系的方式首先就已经排除了,世界坐标和视口坐标好像也都不太合适,最后查了一些资料,最终还是找到了转换方法,下面就进行分享。
先简单介绍一下几种坐标系吧
世界坐标
世界坐标很好理解,它是一个3D坐标。就是游戏物体在你创造世界中的坐标。transform.position
相对坐标
相对坐标系,就是物体本身相对于父物体的坐标位置。transform.localPosition;
屏幕坐标
屏幕坐标是以像素来定义的,与分辨率有关,例如分辨率为1920*1080的屏幕则Screen.width为1920,Screen.height为1080。
屏幕的左下角坐标为(0 , 0),右上角为(Screen.width , Screen.height),z轴坐标是相机的世界坐标中z轴的负值,我们常用的Input.mousePosition和移动端的Input.GetTouch(0).position都是获得的光标在屏幕坐标的位置
视口坐标
视口坐标系其实就是将屏幕坐标系单位化视口坐标的左下角为(0 , 0),右上角为(1 , 1),z轴坐标是相机的世界坐标中z轴的负值
步入今天的正题吧
RectTransformUtility.ScreenPointToLocalPointInRectangle() 是 UGUI屏幕坐标转UI坐标的方法。但是在网上查了一下,关于这个方法的介绍很少,所以今天想着把这个问题总结成一个笔记,方便以后复习查阅,也希望能帮助到一些碰到相同问题的同行。
先看一下层级排布,ui1和ui2分别隶属于不同的父物体,但是现在我需要让两个ui进行等高处理
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIPositionTest : MonoBehaviour
{
public RectTransform uiParent1;
public RectTransform uiParent2;
public RectTransform ui1;
public RectTransform ui2;
private Vector2 ui1_startPos;
private Vector2 ui2_startPos;
private void Start()
{
ui1_startPos = ui1.localPosition;
ui2_startPos = ui2.localPosition;
}
private void OnGUI()
{
if (GUI.Button(new Rect(20,Screen.height-100,150,80),"UI2向UI1高看齐"))
{
Vector2 ui1ScreenPos = Camera.main.WorldToScreenPoint(ui1.position);
Vector2 localPos;
bool isSucess = RectTransformUtility.ScreenPointToLocalPointInRectangle(uiParent2, ui1ScreenPos, Camera.main, out localPos);
if (isSucess)
{
ui2.localPosition = new Vector3(ui2.localPosition.x,localPos.y,0);
}
}
if (GUI.Button(new Rect(170, Screen.height - 100, 150, 80), "UI1向UI2高看齐"))
{
Vector2 ui2ScreenPos = Camera.main.WorldToScreenPoint(ui2.position);
Vector2 localPos;
bool isSucess = RectTransformUtility.ScreenPointToLocalPointInRectangle(uiParent1, ui2ScreenPos, Camera.main, out localPos);
if (isSucess)
{
ui1.localPosition = new Vector3(ui1.localPosition.x, localPos.y, 0);
}
}
if (GUI.Button(new Rect(320, Screen.height - 100, 150, 80), "位置还原"))
{
ui1.localPosition = ui1_startPos;
ui2.localPosition = ui2_startPos;
}
}
}
只需要把这个脚本挂在Canvas上,然后运行工程,可以点击“UI2向UI1高看齐”或者“UI1向UI2高看齐”进行高度对齐,点击“位置还原按钮”可以进行位置恢复。
其中最重要的代码只有一句:**RectTransformUtility.ScreenPointToLocalPointInRectangle() **
这个方法体一共有四个参数,下面分别讲一下:
参数一:需要进行位置改变的ui物体的父物体的RectTransform组件
参数二:参照物体的屏幕坐标
参数三:相机,一般为主相机,或者特殊需求换相机也可
参数四:接收返回值得Vector2类型,这个值就是需要进行位置改变的ui物体的相对坐标
返回值:bool类型,为true时证明转换成功