一、需求
右键触发打开菜单,左键在内部可选择选项,左键单击菜单范围外关闭。难点在于屏幕坐标系,鼠标位置,UI位置之间的关系。
二、理论
前置知识:
unity中,用RectTransform对象的position.x和position.y表示UI在屏幕中(相对于左下角的正值)的位置。而两者所代表的点,就是UI中的Pivot的点。
Pivot中,0也是最左或者最下,都是同一个参考。Pivot( 0,1)则表示,UI坐标点选取为最左边,最上边,也就是左上角,用0-1的比例表示。细心可以发现Pivot就是一个空心圆。这个点就表示UI的位置点。
从1920换到3840的分辨率后,虽然UI可以做比例大小适应,但是rect中的width和height属性是不会变的,就是制作UI时输入的数值。所以如果要改分辨率做适配,这两个值不能直接用,要根据屏幕比例去计算真正的宽高。
调整后的宽高为:(小学的等比计算)
float adaptScaleWidth = Screen.width * (menuRect.rect.width / 1920f); float adaptScaleHeight = Screen.height * (menuRect.rect.height / 1080f);
鼠标在屏幕中的位置:左下角为零点,右上增加,分辨率更改,鼠标在屏幕中的位置值也不同。直接用api获取:
Input.mousePosition.x
Input.mousePosition.y
三、关键代码
1.右键打开事件
public class CustomBtn : MonoBehaviour,IPointerDownHandler
{
void Start()
{
}
public void OnPointerDown(PointerEventData eventData)
{
//你要触发的代码
if (eventData.button==PointerEventData.InputButton.Right)
{
RightClickMenuPanel.Instance.menuRect.position = Input.mousePosition;
RightClickMenuPanel.Instance.ShowRightClickMenu(true);
}
}
继承 IPointerDownHandler,实现OnPointerDown,用PointerEventData判定按键。先设定右键菜单的pivot位置,再打开setactive(true)。
二、判定
private void Update()
{
//左键关闭情况
if (Input.GetMouseButtonDown(0))
{
float adaptScaleWidth = Screen.width * (menuRect.rect.width / 1920f);
float adaptScaleHeight = Screen.height * (menuRect.rect.height / 1080f);
//超出菜单范围关闭
if (Input.mousePosition.x<menuRect.position.x ||
Input.mousePosition.x>menuRect.position.x+ adaptScaleWidth ||
Input.mousePosition.y<menuRect.position.y- adaptScaleHeight ||
Input.mousePosition.y>menuRect.position.y
)
{
ShowRightClickMenu(false);
}
}
}
public void ShowRightClickMenu(bool flag)
{
menuRect.gameObject.SetActive(flag);
}
在其他地方挂脚本,换算,判定鼠标位置,在范围外设置关闭。