Example #1
0
 // 注销碰撞器
 public void unregisteCollider(IMouseEventCollect obj)
 {
     if (!mAllObjectSet.Contains(obj))
     {
         return;
     }
     if (mHoverWindow == obj)
     {
         mHoverWindow = null;
     }
     if (obj is myUIObject)
     {
         int count = mMouseCastWindowList.Count;
         for (int i = 0; i < count; ++i)
         {
             MouseCastWindowSet item = mMouseCastWindowList[i];
             if (item.hasWindow(obj))
             {
                 item.removeWindow(obj);
                 if (item.isEmpty())
                 {
                     mMouseCastWindowList.Remove(item);
                 }
                 break;
             }
         }
         --mUGUICount;
     }
     else if (obj is MovableObject)
     {
         int count = mMouseCastObjectList.Count;
         for (int i = 0; i < count; ++i)
         {
             MouseCastObjectSet item = mMouseCastObjectList[i];
             if (item.hasObject(obj))
             {
                 item.removeObject(obj);
                 if (item.isEmpty())
                 {
                     mMouseCastObjectList.Remove(item);
                 }
                 break;
             }
         }
         mMovableObjectList.Remove(obj);
     }
     mAllObjectSet.Remove(obj);
     mMouseDownWindowList.Remove(obj);
     mMultiTouchWindowList.Remove(obj);
 }
 //-------------------------------------------------------------------------------------------------------
 protected static int depthDescend(MouseCastObjectSet a, MouseCastObjectSet b)
 {
     if (a.mCamera == null && b.mCamera == null)
     {
         return(0);
     }
     if (a.mCamera == null)
     {
         return(1);
     }
     if (b.mCamera == null)
     {
         return(-1);
     }
     return((int)sign(b.mCamera.getCameraDepth() - a.mCamera.getCameraDepth()));
 }
 public static int depthDescend(MouseCastObjectSet a, MouseCastObjectSet b)
 {
     if (a.mCamera == null && b.mCamera == null)
     {
         return(0);
     }
     if (a.mCamera == null)
     {
         return(1);
     }
     if (b.mCamera == null)
     {
         return(-1);
     }
     return((int)MathUtility.sign(b.mCamera.getCameraDepth() - a.mCamera.getCameraDepth()));
 }
Example #4
0
 // 注册碰撞器,只有注册了的碰撞器才会进行检测
 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);
     }
 }
Example #5
0
    // 全局射线检测
    protected List <IMouseEventCollect> globalRaycast(ref Vector3 mousePos, bool ignorePassRay = false)
    {
        bool continueRay = true;

        mTempList2.Clear();
        // 每次检测UI时都需要对列表按摄像机深度进行降序排序
        quickSort(mMouseCastWindowList, MouseCastWindowSet.mComparisonDescend);
        int windowSetCount = mMouseCastWindowList.Count;

        for (int i = 0; i < windowSetCount; ++i)
        {
            var item = mMouseCastWindowList[i];
            if (!continueRay)
            {
                break;
            }
            // 检查摄像机是否被销毁
            if (item.getCamera() == null || item.getCamera().isDestroy())
            {
                logError("摄像机已销毁:" + item.getCamera().getName());
                continue;
            }
            getCameraRay(ref mousePos, out Ray ray, item.getCamera().getCamera());
            raycastLayout(ref ray, item.getWindowOrderList(), mTempList2, ref continueRay, false, ignorePassRay);
        }
        // UI层允许当前鼠标射线穿过时才检测场景物体
        if (continueRay)
        {
            quickSort(mMouseCastObjectList, MouseCastObjectSet.mCompareDescend);
            int objSetCount = mMouseCastObjectList.Count;
            for (int i = 0; i < objSetCount; ++i)
            {
                MouseCastObjectSet item = mMouseCastObjectList[i];
                if (!continueRay)
                {
                    break;
                }
                // 检查摄像机是否被销毁
                if (item.mCamera != null && item.mCamera.isDestroy())
                {
                    logError("摄像机已销毁:" + item.mCamera.getName());
                    continue;
                }
                Camera camera;
                if (item.mCamera == null)
                {
                    GameCamera mainCamera = mCameraManager.getMainCamera();
                    if (mainCamera == null)
                    {
                        logError("找不到主摄像机,无法检测摄像机射线碰撞");
                        continue;
                    }
                    camera = mainCamera.getCamera();
                }
                else
                {
                    camera = item.mCamera.getCamera();
                }
                getCameraRay(ref mousePos, out Ray ray, camera);
                raycastMovableObject(ref ray, item.mObjectOrderList, mTempList2, ref continueRay, false);
            }
        }
        return(mTempList2);
    }
Example #6
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);
 }
Example #7
0
    public override void update(float elapsedTime)
    {
        if (!mUseHover || !mUseGlobalTouch)
        {
            return;
        }
        int touchCount = Input.touchCount;

        // 多点触控和单点触控需要分开判断
        if (touchCount >= 2)
        {
            // 此处未考虑到触点离开窗口时以及再次进入窗口所引起的结束多点触控和开始多点触控的判断
            LIST(out List <IMouseEventCollect> endMultiWindow);
            mTempMultiTouchPoint.Clear();
            mTempStartMultiWindow.Clear();
            mTempMovingMultiWindow.Clear();
            mTouchInWindow.Clear();
            // 查找触点所在窗口
            for (int i = 0; i < touchCount; ++i)
            {
                Touch touch = Input.GetTouch(i);
                mTempMultiTouchPoint.Add(touch.fingerId, touch);
                Vector3            touchPosition = new Vector3(touch.position.x, touch.position.y, 0.0f);
                IMouseEventCollect hoverWindow   = getHoverWindow(ref touchPosition);
                if (hoverWindow != null)
                {
                    if (!mTouchInWindow.TryGetValue(hoverWindow, out Dictionary <int, Touch> touchList))
                    {
                        touchList = new Dictionary <int, Touch>();
                        mTouchInWindow.Add(hoverWindow, touchList);
                    }
                    // 每个窗口最多有两个触点
                    if (touchList.Count < 2)
                    {
                        touchList.Add(touch.fingerId, touch);
                    }
                }
            }
            // 判断哪些窗口上一帧还拥有两个触点,但是这一帧不足两个触点,则是
            foreach (var item in mTouchInWindow)
            {
                var touchesInWindow = item.Value;
                if (touchesInWindow.Count == 2)
                {
                    // 结束多点触控
                    bool isEnd   = false;
                    bool isStart = false;
                    foreach (var touches in touchesInWindow)
                    {
                        // 有触点结束了,则认为多点触控已经结束
                        if (touches.Value.phase == TouchPhase.Ended || touches.Value.phase == TouchPhase.Canceled)
                        {
                            isEnd = true;
                        }
                        // 有触点刚开始,则认为开始多点触控
                        else if (touches.Value.phase == TouchPhase.Began)
                        {
                            isStart = true;
                        }
                    }
                    if (isEnd)
                    {
                        endMultiWindow.Add(item.Key);
                    }
                    else if (isStart)
                    {
                        mTempStartMultiWindow.Add(item.Key, new List <Touch>(touchesInWindow.Values));
                    }
                    else
                    {
                        mTempMovingMultiWindow.Add(item.Key, new List <Touch>(touchesInWindow.Values));
                    }
                }
            }
            // 新增的多点触控窗口
            foreach (var item in mTempStartMultiWindow)
            {
                if (!mMultiTouchWindowList.ContainsKey(item.Key))
                {
                    CLASS(out MultiTouchInfo info);
                    info.mWindow         = item.Key;
                    info.mPhase          = TouchPhase.Began;
                    info.mFinger0        = item.Value[0].fingerId;
                    info.mFinger1        = item.Value[1].fingerId;
                    info.mStartPosition0 = item.Value[0].position;
                    info.mStartPosition1 = item.Value[1].position;
                    info.mCurPosition0   = info.mStartPosition0;
                    info.mCurPosition1   = info.mStartPosition1;
                    mMultiTouchWindowList.Add(item.Key, info);
                }
                item.Key.onMultiTouchStart(item.Value[0].position, item.Value[1].position);
            }
            // 更新已存在的多点触控窗口
            foreach (var item in mMultiTouchWindowList)
            {
                IMouseEventCollect window = item.Key;
                if (mTempMovingMultiWindow.ContainsKey(window))
                {
                    Touch touch0 = mTempMultiTouchPoint[item.Value.mFinger0];
                    Touch touch1 = mTempMultiTouchPoint[item.Value.mFinger1];
                    if (!isVectorEqual(touch0.position, item.Value.mCurPosition0) || !isVectorEqual(touch1.position, item.Value.mCurPosition1))
                    {
                        window.onMultiTouchMove(touch0.position, item.Value.mCurPosition0, touch1.position, item.Value.mCurPosition1);
                        item.Value.mCurPosition0 = touch0.position;
                        item.Value.mCurPosition1 = touch1.position;
                        item.Value.mPhase        = TouchPhase.Moved;
                    }
                    else
                    {
                        item.Value.mPhase = TouchPhase.Stationary;
                    }
                }
            }
            // 结束多点触控的窗口
            int endCount = endMultiWindow.Count;
            for (int i = 0; i < endCount; ++i)
            {
                IMouseEventCollect item = endMultiWindow[i];
                item.onMultiTouchEnd();
                if (mMultiTouchWindowList.TryGetValue(item, out MultiTouchInfo info))
                {
                    UN_CLASS(info);
                    mMultiTouchWindowList.Remove(item);
                }
            }
            UN_LIST(endMultiWindow);
        }
        else
        {
            // 手指操作触摸屏
            if (touchCount == 1)
            {
                Touch touch = Input.GetTouch(0);
                if (touch.phase == TouchPhase.Began)
                {
                    notifyGlobalPress(true);
                }
                else if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
                {
                    notifyGlobalPress(false);
                }
            }
            // 鼠标点击屏幕
            else if (touchCount == 0)
            {
                if (mInputManager.getMouseCurrentDown(MOUSE_BUTTON.LEFT))
                {
                    notifyGlobalPress(true);
                }
                else if (mInputManager.getMouseCurrentUp(MOUSE_BUTTON.LEFT))
                {
                    notifyGlobalPress(false);
                }
            }
            // 模拟触摸时,更新触摸点
            if (mSimulateTouch && mMousePressed)
            {
                mCurTouchPosition = Input.mousePosition;
            }
            // 鼠标移动检测
            Vector3 curMousePosition = getCurMousePosition();
            if (!isVectorEqual(ref mLastMousePosition, ref curMousePosition))
            {
                // 检查当前悬停窗口
                checkHoverWindow(ref curMousePosition, true);
                // 鼠标移动事件
                Vector3 moveDelta = curMousePosition - mLastMousePosition;
                mHoverWindow?.onMouseMove(ref curMousePosition, ref moveDelta, elapsedTime);
                // 给鼠标按下时选中的所有窗口发送鼠标移动的消息
                int count = mMouseDownWindowList.Count;
                for (int i = 0; i < count; ++i)
                {
                    IMouseEventCollect item = mMouseDownWindowList[i];
                    if (item != mHoverWindow)
                    {
                        item.onMouseMove(ref curMousePosition, ref moveDelta, elapsedTime);
                    }
                }
                mLastMousePosition = curMousePosition;
                // 如果在一个窗口上停留超过0.05秒没有移动,则触发停留在窗口上的事件
                mStayTimer.start();
            }
            else
            {
                if (mStayTimer.tickTimer(elapsedTime))
                {
                    mHoverWindow?.onMouseStay(curMousePosition);
                    // 给鼠标按下时选中的所有窗口发送鼠标移动的消息
                    int count = mMouseDownWindowList.Count;
                    for (int i = 0; i < count; ++i)
                    {
                        mMouseDownWindowList[i].onMouseStay(curMousePosition);
                    }
                }
            }
        }
        // 检查摄像机是否被销毁
        int windowCount = mMouseCastWindowList.Count;

        for (int i = 0; i < windowCount; ++i)
        {
            MouseCastWindowSet item = mMouseCastWindowList[i];
            if (item.getCamera() != null && item.getCamera().isDestroy())
            {
                logError("摄像机已销毁:" + item.getCamera().getName());
            }
        }
        int objCount = mMouseCastObjectList.Count;

        for (int i = 0; i < objCount; ++i)
        {
            MouseCastObjectSet item = mMouseCastObjectList[i];
            if (item.mCamera != null && item.mCamera.isDestroy())
            {
                logError("摄像机已销毁:" + item.mCamera.getName());
            }
        }
    }