一、需求
右键触发打开菜单,左键在内部可选择选项,左键单击菜单范围外关闭。难点在于屏幕坐标系,鼠标位置,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);}
在其他地方挂脚本,换算,判定鼠标位置,在范围外设置关闭。