zoukankan      html  css  js  c++  java
  • unity5, UGUI刺穿问题解法

    我希望在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;

    using UnityEngine.UI; 

       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&&graphicRaycaster.enabled==true) {
                    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不只是会搜索子节点,也会搜索孙节点。

    二,加上graphicRaycaster.enabled==true的判断,好处是,如果我们希望某个Canvas能被刺穿,则可以将其Graphic Raycaster去掉勾选即可。

    参考:http://www.cnblogs.com/fly-100/p/4570366.html

  • 相关阅读:
    thinkphp 3.2 服务器 session 设置时间周期失效问题 服务器是linux windows 上暂时没有发现此类问题
    php 不常见的开发模式
    js 里面的 call 方法 和 apply 方法
    PHP读取文件目录, 并显示需要的目录
    PHP 时间格式
    Python之旅.第三章.函数
    Python之旅.第三章.函数
    Python之旅.第三章.函数
    Python之旅.第三章.函数
    Python之旅.第三章.函数
  • 原文地址:https://www.cnblogs.com/wantnon/p/4606577.html
Copyright © 2011-2022 走看看