最近有一个需求:有一个二级展示界面,在点击空白处时关闭这个界面。如果空白处是一级界面的某个按钮或者滑动条,要执行这个按钮活滑动条的功能。
很闹心,一开始的想法是在二级下面加一个巨大的button,点击关闭。但是这样就无法执行一级界面的方法了。如果不加button,一级界面上的东西那么多,难道要在每个按钮上都加一个关闭二级界面的通知吗……
问了马三能不能做成点击穿透……
他表示这么做麻烦,我只好和策划沟通表示先放着。最近有一个类似的功能,看来不做不行了。
花了几天时间搜一搜,觉得自己是个神经病,人家特意把下面的都拦截掉了,我居然还要搞出来。
然后今天在搜用射线的时候,突然想到,我可以监听屏幕点击就行了啊!
好了,废话不多说。开始正文。
总体上是这样的,一开始的时候,image是隐藏的,点击按钮时,image显示出来。然后在点击任意位置或拖动这个slider时,image隐藏。但是,如果点在按钮上,image还是显示的。
先上按钮部分的代码
void Start()
{
if (null != button)
{
button.onClick.AddListener(() =>
{
IsShowImage(true);
});
}
}
public void IsShowImage(bool isShow)
{
if (null != image)
{
image.gameObject.SetActive(isShow);
}
}
点击按钮隐藏就好了
接下来是image的部分
首先先把RaycastTarget勾掉,不然点击时会把点击到按钮的射线拦截掉。
然后在image上挂一个脚本
脚本代码
private bool isButtonDown = false;
private Vector3 startMousePos;
void Update()
{
//按下
if (Input.GetMouseButtonDown(0))
{
startMousePos = Input.mousePosition;
isButtonDown = true;
}
//拖动
if (true == isButtonDown)
{
Vector3 mousePos = Input.mousePosition;
float dictX = mousePos.x - startMousePos.x;
float dictY = mousePos.y - startMousePos.y;
if ((10 < dictX) || (-10 > dictX) || (10 < dictY) || (-10 > dictY))
{
isButtonDown = false;
gameObject.SetActive(false);
this.transform.parent.GetComponent<Test>().IsShowImage(false);
}
}
//松开
if (Input.GetMouseButtonUp(0))
{
isButtonDown = false;
this.transform.parent.GetComponent<Test>().IsShowImage(false);
}
}
简单易懂,就不多说了。
这里其实有一个坑:当你点击按钮时,会先执行按钮的OnClick,再执行Input的GetMouseButtonUp
所以稍微修改一下关于图片显示的代码:
private int showCount = 0;
public void IsShowImage(bool isShow)
{
if (null != image)
{
if (true == isShow)
{
showCount++;
}
else
{
showCount--;
}
image.gameObject.SetActive(0 < showCount);
}
}
用一个数值来记录次数 按钮触发就加一,屏幕点击就减一,这样就能保证正确了。
其实这个方法总的来说还是挺不好看的,写的不太好,希望有真正的能解决这个问题还没有太大消耗的方法……【继续干(hua)活(shui)】