我希望在touch屏幕时player起跳,于是在playerControl.cs的Update函数中添加如下touch代码:
if (Input.GetMouseButtonDown (0)) {//left button down
jump ();
}
同时我在屏幕左上角加了一个实现暂停的pause按钮,用的是Unity的UI Button。
于是问题来了,当我点pause按钮想暂停时,人物同时也会起跳!
即Button响应touch消息后并没能把它拦截下来,touch消息刺穿Button到达了屏幕。
解决UGUI刺穿问题目前在所有平台都有效的办法是在屏幕响应touch前先用graphicRaycaster当前touch是否落在ui上。
举例说明如下:
假设我的项目UI部分Hierarchy如下:
在UI节点上的脚本UIcontrol.cs中实现如下函数:
using UnityEngine.EventSystems;
using System.Collections.Generic;
public bool isTouchOnUI()
{
EventSystem eventSystem = gameObject.transform.FindChild ("EventSystem").GetComponent<EventSystem> ();
Transform[] childrenTransformList = GetComponentsInChildren<Transform>();
foreach (Transform transform in childrenTransformList) {
GraphicRaycaster graphicRaycaster = transform.GetComponent<GraphicRaycaster> ();
if (graphicRaycaster) {
PointerEventData eventData = new PointerEventData (eventSystem);
eventData.pressPosition = Input.mousePosition;
eventData.position = Input.mousePosition;
List<RaycastResult> list = new List<RaycastResult> ();
graphicRaycaster.Raycast (eventData, list);
////Debug.Log("list.Count:"+list.Count);
if (list.Count > 0)
return true;
}
}
return false;
}
那么前面的touch代码改为:
bool isTouchOnUI=m_gameRef.transform.Find("UI").GetComponent<UIcontrol>().isTouchOnUI();
if (isTouchOnUI==false&&Input.GetMouseButtonDown (0)) {//left button down
jump ();
}
即可解决touch穿透问题。
补充:
一定要加if(graphicRaycaster)的判断,因为注意GameObject.GetComponentsInChildren的文档中写道:
Returns all components of Type type
in the GameObject or any of its children.
即,除了UI节点的孩子会被搜索以外,UI节点本身也会被搜索,而UI节点上不含有graphicRaycaster,所以必须先判断graphicRaycaster是否获得成功,再进行后续处理。
另外文档中还写道:
The search for components is carried out recursively on child objects, so it includes children of children, and so on.
即GameObject.GetComponentsInChildren不只是会搜索子节点,也会搜索孙节点。
参考:http://www.cnblogs.com/fly-100/p/4570366.html