// ignorePassRay表示是否忽略窗口的isPassRay属性,true表示认为所有的都允许射线穿透
    protected void raycastLayout(ref Ray ray, SortedDictionary <UIDepth, List <IMouseEventCollect> > windowOrderList,
                                 List <IMouseEventCollect> retList, ref bool continueRay, bool clearList = true,
                                 int maxCount = 0, bool ignorePassRay = false)
    {
        if (clearList)
        {
            retList.Clear();
        }
        continueRay = true;
        RaycastHit hit;

        foreach (var box in windowOrderList)
        {
            int count = box.Value.Count;
            for (int i = 0; i < count; ++i)
            {
                IMouseEventCollect window = box.Value[i];
                if (window.isActive() && window.isHandleInput() && window.getCollider().Raycast(ray, out hit, 10000.0f))
                {
                    // 点击了只允许部分穿透的背景
                    if (mPassOnlyArea.ContainsKey(window))
                    {
                        IMouseEventCollect child = mPassOnlyArea[window];
                        //判断是否点到了背景中允许穿透的部分,如果是允许穿透的部分,则射线可以继续判断下层的窗口,否则不允许再继续穿透
                        continueRay = child.isActive() && child.isHandleInput() && child.getCollider().Raycast(ray, out hit, 10000.0f);
                        if (!continueRay)
                        {
                            break;
                        }
                    }
                    else
                    {
                        retList.Add(window);
                        // 如果射线不能穿透当前按钮,或者已经达到最大数量,则不再继续
                        bool passRay      = ignorePassRay || window.isPassRay();
                        bool countNotFull = maxCount <= 0 || retList.Count < maxCount;
                        continueRay = passRay && countNotFull;
                        if (!continueRay)
                        {
                            break;
                        }
                    }
                }
            }
            if (!continueRay)
            {
                break;
            }
        }
    }
Beispiel #2
0
    protected void raycastMovableObject(ref Ray ray, List <IMouseEventCollect> moveObjectList, List <IMouseEventCollect> retList, ref bool continueRay, bool clearList = true)
    {
        if (clearList)
        {
            retList.Clear();
        }
        continueRay = true;
        RaycastHit hit;

        LIST(out List <DistanceSortHelper> sortList);
        int objCount = moveObjectList.Count;

        for (int i = 0; i < objCount; ++i)
        {
            IMouseEventCollect box = moveObjectList[i];
            // 将所有射线碰到的物体都放到列表中
            if (box.isActive() && box.isHandleInput() && box.getCollider().Raycast(ray, out hit, 10000.0f))
            {
                sortList.Add(new DistanceSortHelper(getSquaredLength(hit.point - ray.origin), box));
            }
        }
        // 根据相交点由近到远的顺序排序
        quickSort(sortList, DistanceSortHelper.mCompareAscend);
        int sortCount = sortList.Count;

        for (int i = 0; i < sortCount; ++i)
        {
            DistanceSortHelper item = sortList[i];
            retList.Add(item.mObject);
            if (!item.mObject.isPassRay())
            {
                continueRay = false;
                break;
            }
        }
        UN_LIST(sortList);
    }
 // 注册碰撞器,只有注册了的碰撞器才会进行检测
 public void registeBoxCollider(IMouseEventCollect button,
                                ObjectClickCallback clickCallback = null,
                                ObjectPressCallback pressCallback = null,
                                ObjectHoverCallback hoverCallback = null,
                                GameCamera camera = null)
 {
     if (!mUseGlobalTouch)
     {
         logError("Not Active Global Touch!");
         return;
     }
     if (button.getCollider() == null)
     {
         logError("window must has collider that can registeBoxCollider! " + button.getName());
         return;
     }
     button.setClickCallback(clickCallback);
     button.setPressCallback(pressCallback);
     button.setHoverCallback(hoverCallback);
     if (!mAllButtonSet.Contains(button))
     {
         if (button is txUIObject)
         {
             // 寻找窗口对应的摄像机
             if (WidgetUtility.isNGUI((button as txUIObject).getObject()))
             {
                 ++mNGUICount;
                 if (camera == null)
                 {
                     camera = mCameraManager.getUICamera(true);
                 }
             }
             else
             {
                 ++mUGUICount;
                 if (camera == null)
                 {
                     camera = mCameraManager.getUICamera(false);
                 }
             }
             if (camera == null)
             {
                 logError("can not find ui camera for raycast!");
             }
             // 将窗口加入到鼠标射线检测列表中
             UIDepth            depth        = button.getUIDepth();
             MouseCastWindowSet mouseCastSet = null;
             foreach (var item in mMouseCastWindowList)
             {
                 if (item.mCamera == camera)
                 {
                     mouseCastSet = item;
                     break;
                 }
             }
             if (mouseCastSet == null)
             {
                 mouseCastSet = new MouseCastWindowSet(camera);
                 mMouseCastWindowList.Add(mouseCastSet);
             }
             mouseCastSet.addWindow(depth, button);
             mButtonDepthList.Add(button, depth);
         }
         else if (button is MovableObject)
         {
             MouseCastObjectSet mouseCastSet = null;
             foreach (var item in mMouseCastObjectList)
             {
                 if (item.mCamera == camera)
                 {
                     mouseCastSet = item;
                     break;
                 }
             }
             if (mouseCastSet == null)
             {
                 mouseCastSet = new MouseCastObjectSet(camera);
                 mMouseCastObjectList.Add(mouseCastSet);
             }
             mouseCastSet.addObject(button);
             mMovableObjectList.Add(button);
         }
         mAllButtonList.Add(button);
         mAllButtonSet.Add(button);
     }
 }
Beispiel #4
0
    // ignorePassRay表示是否忽略窗口的isPassRay属性,true表示认为所有的都允许射线穿透
    // 但是ignorePassRay不会影响到PassOnlyArea和ParentPassOnly
    protected void raycastLayout(ref Ray ray,
                                 List <IMouseEventCollect> windowOrderList,
                                 List <IMouseEventCollect> retList,
                                 ref bool continueRay,
                                 bool clearList     = true,
                                 bool ignorePassRay = false)
    {
        if (clearList)
        {
            retList.Clear();
        }
        // mParentPassOnlyList需要重新整理,排除未启用的布局的窗口
        LIST(out List <IMouseEventCollect> activeParentList);
        // 在只允许父节点穿透的列表中已成功穿透的父节点列表
        LIST(out List <IMouseEventCollect> passParent);

        // 筛选出已激活的父节点穿透窗口
        int allParentCount = mParentPassOnlyList.Count;

        for (int i = 0; i < allParentCount; ++i)
        {
            if (mParentPassOnlyList[i].isActiveInHierarchy())
            {
                activeParentList.Add(mParentPassOnlyList[i]);
            }
        }

        // 射线检测
        continueRay = true;
        int windowCount = windowOrderList.Count;

        for (int i = 0; i < windowCount; ++i)
        {
            IMouseEventCollect window = windowOrderList[i];
            if (window.isActiveInHierarchy() && window.isHandleInput() && window.getCollider().Raycast(ray, out _, 10000.0f))
            {
                // 点击到了只允许父节点穿透的窗口,记录到列表中
                // 但是因为父节点一定是在子节点之后判断的,子节点可能已经拦截了射线,从而导致无法检测到父节点
                if (activeParentList.Contains(window))
                {
                    passParent.Add(window);
                    // 特殊窗口暂时不能接收输入事件,所以不放入相交窗口列表中
                    continue;
                }

                // 点击了只允许部分穿透的背景
                if (mPassOnlyArea.TryGetValue(window, out IMouseEventCollect passOnlyArea))
                {
                    //判断是否点到了背景中允许穿透的部分,如果是允许穿透的部分,则射线可以继续判断下层的窗口,否则不允许再继续穿透
                    continueRay = passOnlyArea.isActiveInHierarchy() && passOnlyArea.isHandleInput() && passOnlyArea.getCollider().Raycast(ray, out _, 10000.0f);
                    if (!continueRay)
                    {
                        break;
                    }
                    // 特殊窗口暂时不能接收输入事件,所以不放入相交窗口列表中
                    continue;
                }

                // 如果父节点不允许穿透
                if (!isParentPassed(window, activeParentList, passParent))
                {
                    continue;
                }

                // 射线成功与窗口相交,放入列表
                retList.Add(window);
                // 如果射线不能穿透当前按钮,则不再继续
                continueRay = ignorePassRay || window.isPassRay();
            }
            if (!continueRay)
            {
                break;
            }
        }
        UN_LIST(passParent);
        UN_LIST(activeParentList);
    }
Beispiel #5
0
 // 注册碰撞器,只有注册了的碰撞器才会进行检测
 public void registeCollider(IMouseEventCollect obj, GameCamera camera = null)
 {
     if (!mUseGlobalTouch)
     {
         logError("Not Active Global Touch!");
         return;
     }
     if (obj.getCollider() == null)
     {
         logError("window must has collider that can registeCollider! " + obj.getName());
         return;
     }
     if (mAllObjectSet.Contains(obj))
     {
         logError("不能重复注册窗口碰撞体: " + obj.getName());
         return;
     }
     if (obj is myUIObject)
     {
         // 寻找窗口对应的摄像机
         ++mUGUICount;
         if (camera == null)
         {
             camera = mCameraManager.getUICamera();
         }
         if (camera == null)
         {
             logError("can not find ui camera for raycast!");
         }
         // 将窗口加入到鼠标射线检测列表中
         MouseCastWindowSet mouseCastSet = null;
         int count = mMouseCastWindowList.Count;
         for (int i = 0; i < count; ++i)
         {
             MouseCastWindowSet item = mMouseCastWindowList[i];
             if (item.getCamera() == camera)
             {
                 mouseCastSet = item;
                 break;
             }
         }
         if (mouseCastSet == null)
         {
             mouseCastSet = new MouseCastWindowSet(camera);
             mMouseCastWindowList.Add(mouseCastSet);
         }
         mouseCastSet.addWindow(obj);
     }
     else if (obj is MovableObject)
     {
         MouseCastObjectSet mouseCastSet = null;
         int count = mMouseCastObjectList.Count;
         for (int i = 0; i < count; ++i)
         {
             MouseCastObjectSet item = mMouseCastObjectList[i];
             if (item.mCamera == camera)
             {
                 mouseCastSet = item;
                 break;
             }
         }
         if (mouseCastSet == null)
         {
             mouseCastSet = new MouseCastObjectSet(camera);
             mMouseCastObjectList.Add(mouseCastSet);
         }
         mouseCastSet.addObject(obj);
         mMovableObjectList.Add(obj);
     }
     mAllObjectSet.Add(obj);
 }