//-------------------------------------------------------------------------------------------------------------------------- protected void notifyGlobalPress(bool press) { // 开始触摸时记录触摸状态,同步上一次的触摸位置 if (mSimulateTouch) { mMousePressed = press; if (mMousePressed) { mCurTouchPosition = Input.mousePosition; mLastMousePosition = mCurTouchPosition; } } Vector3 mousePosition = getCurMousePosition(); // 检查当前悬停窗口 checkHoverWindow(ref mousePosition, press); // 通知屏幕鼠标事件 foreach (var item in mAllObjectSet) { if (!item.isReceiveScreenMouse()) { continue; } if (press) { item.onScreenMouseDown(mousePosition); } else { item.onScreenMouseUp(mousePosition); } } var raycast = globalRaycast(ref mousePosition); int count = raycast.Count; for (int i = 0; i < count; ++i) { IMouseEventCollect obj = raycast[i]; // 如果此时窗口已经被销毁了,则不再通知 if (!mAllObjectSet.Contains(obj)) { continue; } if (press) { obj.onMouseDown(mousePosition); } else { obj.onMouseUp(mousePosition); } } // 保存鼠标按下时所选中的所有窗口,需要给这些窗口发送鼠标移动的消息 // 如果鼠标放开,则只是清空列表 mMouseDownWindowList.Clear(); if (press) { mMouseDownWindowList.AddRange(raycast); } }
protected void checkHoverWindow(ref Vector3 mousePos, bool mouseDown) { IMouseEventCollect newWindow = null; // 模拟触摸状态下,如果鼠标未按下,则不会悬停在任何窗口上 if (mouseDown || !mSimulateTouch) { // 计算鼠标当前所在最前端的窗口 newWindow = getHoverWindow(ref mousePos); } // 判断鼠标是否还在当前窗口内 if (mHoverWindow != null) { // 鼠标已经移动到了其他窗口中,发送鼠标离开的事件 if (newWindow != mHoverWindow) { // 不过也许此时悬停窗口已经不接收输入事件了或者碰撞盒子被禁用了,需要判断一下 if (mHoverWindow.isActive() && mHoverWindow.isHandleInput()) { mHoverWindow.onMouseLeave(); } // 找到鼠标所在的新的窗口,给该窗口发送鼠标进入的事件 newWindow?.onMouseEnter(); } } // 如果上一帧鼠标没有在任何窗口内,则计算这一帧鼠标所在的窗口 else { // 发送鼠标进入的事件 newWindow?.onMouseEnter(); } mHoverWindow = newWindow; }
//-------------------------------------------------------------------------------------------------------------- protected bool checkStartTouchDrag(ref Touch touch) { Vector3 mousePosition = touch.position; if (mouseInObject(ref mousePosition)) { // 拖拽消息不向下传递, 从上往下查找,如果前面没有窗口需要有拖拽消息被处理,则当前窗口响应拖拽消息 var hoverWindowList = mGlobalTouchSystem.getAllHoverWindow(ref mousePosition); int count = hoverWindowList.Count; for (int i = 0; i < count; ++i) { IMouseEventCollect item = hoverWindowList[i]; if (item == mComponentOwner as IMouseEventCollect) { onMouseDown(mousePosition); return(true); } if (item.isDragable()) { break; } } } return(false); }
// 有物体拖动到了当前窗口上 public virtual void onReceiveDrag(IMouseEventCollect dragObj, ref bool continueEvent) { if (mReceiveDragCallback != null) { continueEvent = false; mReceiveDragCallback(dragObj, ref continueEvent); } }
public bool hasWindow(UIDepth depth, IMouseEventCollect window) { if (!mWindowOrderList.ContainsKey(depth)) { return(false); } return(mWindowOrderList[depth].Contains(window)); }
public void removeWindow(IMouseEventCollect window) { if (!mWindowSet.Remove(window)) { return; } mWindowOrderList.Remove(window); }
public void addWindow(UIDepth depth, IMouseEventCollect window) { if (!mWindowOrderList.ContainsKey(depth)) { mWindowOrderList.Add(depth, new List <IMouseEventCollect>()); } mWindowOrderList[depth].Add(window); }
// 鼠标在屏幕上抬起 protected void onScreenMouseUp(IMouseEventCollect obj, Vector2 mousePos) { mMouseDown = false; // 正在拖动时鼠标抬起,则开始逐渐减速到0 if (mState == SCROLL_STATE.DRAGING) { mState = SCROLL_STATE.SCROLL_TO_STOP; } }
// parent的区域中只有passOnlyArea的区域可以穿透 public void bindPassOnlyArea(IMouseEventCollect parent, IMouseEventCollect passOnlyArea) { if (!mAllObjectSet.Contains(parent) || !mAllObjectSet.Contains(passOnlyArea)) { logError("需要先注册窗口,才能绑定穿透区域"); return; } mPassOnlyArea.Add(parent, passOnlyArea); }
// parent的区域中才能允许parent的子节点接收射线检测 public void bindPassOnlyParent(IMouseEventCollect parent) { if (!mAllObjectSet.Contains(parent)) { logError("需要先注册窗口,才能绑定父节点穿透区域"); return; } mParentPassOnlyList.Add(parent); }
public void removeWindow(IMouseEventCollect window) { UIDepth depth = window.getUIDepth(); mWindowOrderList[depth].Remove(window); if (mWindowOrderList[depth].Count == 0) { mWindowOrderList.Remove(depth); } }
public void addWindow(IMouseEventCollect window) { if (mWindowSet.Contains(window)) { return; } mWindowOrderList.Add(window); mWindowSet.Add(window); mDepthDirty = true; }
protected void onScreenMouseUp(IMouseEventCollect obj, Vector2 mousePos) { // 调用结束回调 if (!mDraging) { return; } mDraging = false; mSliderEndCallback?.Invoke(); }
public virtual bool isChildOf(IMouseEventCollect parent) { var obj = parent as MovableObject; if (obj == null) { return(false); } return(mTransform.IsChildOf(obj.getTransform())); }
public void resetProperty() { mWindow = null; mFinger0 = 0; mFinger1 = 0; mStartPosition0 = Vector2.zero; mStartPosition1 = Vector2.zero; mCurPosition0 = Vector2.zero; mCurPosition1 = Vector2.zero; mPhase = TouchPhase.Began; }
public void windowDepthChanged(UIDepth lastDepth, IMouseEventCollect window) { // 移除旧的按钮深度 mWindowOrderList[lastDepth].Remove(window); // 添加新的按钮深度 UIDepth newDepth = window.getUIDepth(); if (!mWindowOrderList.ContainsKey(newDepth)) { mWindowOrderList.Add(newDepth, new List <IMouseEventCollect>()); } mWindowOrderList[newDepth].Add(window); }
protected override void onDraging(ref Vector3 mousePos) { base.onDraging(ref mousePos); IMouseEventCollect curHover = mGlobalTouchSystem.getHoverWindow(ref mousePos, mWindow); // 悬停的窗口改变了 if (curHover != mDragHoverWindow) { mDragHoverWindow?.onDragHoverd(mWindow, false); mDragHoverWindow = curHover as myUIObject; mDragHoverWindow?.onDragHoverd(mWindow, true); } mOnDraging?.Invoke(); }
// 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; } } }
// 越顶层的窗口越靠近列表前面 public List <IMouseEventCollect> getAllHoverWindow(ref Vector3 pos, IMouseEventCollect ignoreWindow = null, bool ignorePassRay = false) { var resultList = globalRaycast(ref pos, ignorePassRay); mTempList.Clear(); foreach (var button in resultList) { if (ignoreWindow != button) { mTempList.Add(button); } } return(mTempList); }
// obj的所有父节点中是否允许射线选中obj // bindParentList是当前激活的已绑定的仅父节点区域穿透的列表 // passedParentList是bindParentList中射线已经穿透的父节点 protected bool isParentPassed(IMouseEventCollect obj, List <IMouseEventCollect> bindParentList, List <IMouseEventCollect> passedParentList) { int parentCount = bindParentList.Count; for (int i = 0; i < parentCount; ++i) { // 有父节点,并且父节点未成功穿透时,则认为当前窗口未相交 if (obj.isChildOf(bindParentList[i]) && !passedParentList.Contains(bindParentList[i])) { return(false); } } return(true); }
// 注销碰撞器 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); }
public IMouseEventCollect getHoverWindow(ref Vector3 pos, IMouseEventCollect ignoreWindow = null, bool ignorePassRay = false) { // 返回最上层的窗口 var resultList = globalRaycast(ref pos, ignorePassRay); IMouseEventCollect forwardButton = null; foreach (var button in resultList) { if (ignoreWindow != button) { forwardButton = button; break; } } return(forwardButton); }
// 越顶层的窗口越靠近列表前面 public List <IMouseEventCollect> getAllHoverWindow(ref Vector3 pos, IMouseEventCollect ignoreWindow = null, bool ignorePassRay = false) { var resultList = globalRaycast(ref pos, ignorePassRay); mTempList.Clear(); int count = resultList.Count; for (int i = 0; i < count; ++i) { IMouseEventCollect window = resultList[i]; if (ignoreWindow != window) { mTempList.Add(window); } } return(mTempList); }
public IMouseEventCollect getHoverWindow(ref Vector3 pos, IMouseEventCollect ignoreWindow = null, bool ignorePassRay = false) { // 返回最上层的窗口 var resultList = globalRaycast(ref pos, ignorePassRay); IMouseEventCollect forwardButton = null; int count = resultList.Count; for (int i = 0; i < count; ++i) { IMouseEventCollect window = resultList[i]; if (ignoreWindow != window) { forwardButton = window; break; } } return(forwardButton); }
protected void checkStartDrag(Vector3 mousePosition) { if (mInputManager.getMouseDown(MOUSE_BUTTON.LEFT) && mouseInObject(ref mousePosition)) { // 从上往下查找,如果前面没有窗口需要有拖拽消息被处理,则当前窗口响应拖拽消息 var hoverWindowList = mGlobalTouchSystem.getAllHoverWindow(ref mousePosition); int count = hoverWindowList.Count; for (int i = 0; i < count; ++i) { IMouseEventCollect item = hoverWindowList[i]; if (item == mComponentOwner as IMouseEventCollect) { onMouseDown(mousePosition); break; } else if (item.isDragable()) { break; } } } }
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 notifyWindowDepthChanged(IMouseEventCollect button) { // 只判断UI的深度变化 if (!(button is txUIObject)) { return; } // 如果之前没有记录过,则不做判断 if (!mAllButtonSet.Contains(button)) { return; } UIDepth lastDepth = mButtonDepthList[button]; foreach (var item in mMouseCastWindowList) { if (item.hasWindow(lastDepth, button)) { item.windowDepthChanged(lastDepth, button); break; } } mButtonDepthList[button] = button.getUIDepth(); }
public void notifyWindowDepthChanged(IMouseEventCollect button) { // 只判断UI的深度变化 if (!(button is myUIObject)) { return; } // 如果之前没有记录过,则不做判断 if (!mAllObjectSet.Contains(button)) { return; } int count = mMouseCastWindowList.Count; for (int i = 0; i < count; ++i) { MouseCastWindowSet item = mMouseCastWindowList[i]; if (item.hasWindow(button)) { item.windowDepthChanged(); break; } } }
// 注销碰撞器 public void unregisteBoxCollider(IMouseEventCollect obj) { if (!mAllButtonSet.Contains(obj)) { return; } if (mHoverWindow == obj) { mHoverWindow = null; } if (obj is txUIObject) { // 从深度列表中移除 UIDepth depth = mButtonDepthList[obj]; mButtonDepthList.Remove(obj); UIDepth curDepth = obj.getUIDepth(); if (depth.mPanelDepth != curDepth.mPanelDepth || !isFloatEqual(depth.mWindowDepth, curDepth.mWindowDepth)) { logError("depth error"); } foreach (var item in mMouseCastWindowList) { if (item.hasWindow(depth, obj)) { item.removeWindow(obj); if (item.isEmpty()) { mMouseCastWindowList.Remove(item); } break; } } if (WidgetUtility.isNGUI((obj as txUIObject).getObject())) { --mNGUICount; } else { --mUGUICount; } } else if (obj is MovableObject) { foreach (var item in mMouseCastObjectList) { if (item.hasObject(obj)) { item.removeObject(obj); if (item.isEmpty()) { mMouseCastObjectList.Remove(item); } break; } } mMovableObjectList.Remove(obj); } mAllButtonList.Remove(obj); mAllButtonSet.Remove(obj); mMouseDownWindowList.Remove(obj); mMultiTouchWindowList.Remove(obj); }
public void bindPassOnlyArea(IMouseEventCollect parent, IMouseEventCollect passOnlyArea) { mPassOnlyArea.Add(parent, passOnlyArea); }