// 将锚点设置到相对于父节点的中心,并且大小不改变 protected void setToNearParentCenterFixedSize() { Vector3[] sides = null; UIRect parentRect = WidgetUtility.findParentRect(gameObject); if (parentRect == null) { sides = getSides(null); } else { sides = getSides(parentRect.gameObject); } for (int i = 0; i < 4; ++i) { mAnchorPoint[i].setRelative(0.0f); if (i == 0 || i == 2) { mAnchorPoint[i].setAbsolute(sides[i].x); } else { mAnchorPoint[i].setAbsolute(sides[i].y); } } }
//------------------------------------------------------------------------------------------------------------------------------------------ public Vector3[] getLocalMinMaxPixelPos() { // 获得第一个带widget的父节点的rect UIRect rect = WidgetUtility.findParentRect(mObject); Vector2 parentWidgetSize = WidgetUtility.getRectSize(rect); // 计算父节点的世界缩放 Vector3 worldScale = getMatrixScale(mTransform.parent.localToWorldMatrix); txUIObject root = mLayout.isNGUI() ? mLayoutManager.getNGUIRoot() : mLayoutManager.getUGUIRoot(); Vector3 uiRootScale = root.getTransform().localScale; Vector2 parentScale = new Vector2(worldScale.x / uiRootScale.x, worldScale.y / uiRootScale.y); // 计算移动的位置范围 Vector2 minPos = new Vector2(parentWidgetSize.x / 2.0f * mMinRelativePos.x / parentScale.x, parentWidgetSize.y / 2.0f * mMinRelativePos.y / parentScale.y); Vector2 maxPos = new Vector2(parentWidgetSize.x / 2.0f * mMaxRelativePos.x / parentScale.x, parentWidgetSize.y / 2.0f * mMaxRelativePos.y / parentScale.y); if (mClampType == CLAMP_TYPE.CT_EDGE) { Vector2 thisSize = getWindowSize(true); minPos += thisSize / 2.0f; maxPos -= thisSize / 2.0f; if (!mClampInner) { swap(ref minPos, ref maxPos); } } else if (mClampType == CLAMP_TYPE.CT_CENTER) { } return(new Vector3[2] { minPos, maxPos }); }
protected void updateRect(bool force = false) { if (!force && !mDirty) { return; } mDirty = false; float width = 0.0f; float height = 0.0f; Vector3 pos = Vector3.zero; UIRect parentRect = WidgetUtility.findParentRect(gameObject); if (parentRect != null) { GameObject parent = parentRect.gameObject; mParentSides = WidgetUtility.getParentSides(parent); float thisLeft = mAnchorPoint[0].mRelative * mParentSides[2].x + mAnchorPoint[0].mAbsolute; float thisRight = mAnchorPoint[2].mRelative * mParentSides[2].x + mAnchorPoint[2].mAbsolute; float thisTop = mAnchorPoint[1].mRelative * mParentSides[1].y + mAnchorPoint[1].mAbsolute; float thisBottom = mAnchorPoint[3].mRelative * mParentSides[1].y + mAnchorPoint[3].mAbsolute; width = thisRight - thisLeft; height = thisTop - thisBottom; pos.x = (thisRight + thisLeft) / 2.0f; pos.y = (thisTop + thisBottom) / 2.0f; } else { width = mAnchorPoint[2].mAbsolute - mAnchorPoint[0].mAbsolute; height = mAnchorPoint[1].mAbsolute - mAnchorPoint[3].mAbsolute; } if (width < 0) { UnityUtility.logError("width error in anchor!"); } if (height < 0) { UnityUtility.logError("height error in anchor!"); } UIWidget thisWidget = WidgetUtility.getGameObjectWidget(gameObject); // 没有widget则是panel,panel是没有宽高的 if (thisWidget != null) { thisWidget.width = (int)(width + 0.5f); thisWidget.height = (int)(height + 0.5f); } Transform thisTrans = gameObject.transform; thisTrans.localPosition = pos; }
// 将锚点设置到相对于父节点的中心,并且各边界距离父节点对应边界占的比例固定,但是如果父节点为空,则只能固定大小 protected void setToNearParentCenterScaleSize() { UIRect parentRect = WidgetUtility.findParentRect(gameObject); if (parentRect == null) { Vector3[] sides = getSides(null); for (int i = 0; i < 4; ++i) { mAnchorPoint[i].setRelative(0.0f); if (i == 0 || i == 2) { mAnchorPoint[i].setAbsolute(sides[i].x); } else { mAnchorPoint[i].setAbsolute(sides[i].y); } } } else { GameObject parent = parentRect.gameObject; Vector3[] sides = getSides(parent); Vector3[] parentSides = WidgetUtility.getParentSides(parent); for (int i = 0; i < 4; ++i) { mAnchorPoint[i].setAbsolute(0.0f); if (i == 0 || i == 2) { mAnchorPoint[i].setRelative(sides[i].x / parentSides[2].x); } else { mAnchorPoint[i].setRelative(sides[i].x / parentSides[1].y); } } } }
static void Calculation() { if (Selection.activeGameObject == null) { return; } ScaleAnchor anchor = Selection.activeGameObject.GetComponent <ScaleAnchor>(); if (anchor == null) { return; } var obj = Selection.activeGameObject; Vector2 thisPos = obj.transform.localPosition; // 获取父物体的属性 UIRect parentRect = WidgetUtility.findParentRect(obj); Vector2 parentSize = WidgetUtility.getRectSize(parentRect); // 计算 anchor.mHorizontalRelativePos = thisPos.x / parentSize.x * 2; anchor.mVerticalRelativePos = thisPos.y / parentSize.y * 2; // 设置成自定义方式 anchor.mPadding = PADDING_STYLE.PS_CUSTOM_VALUE; }
public override void update(float elapsedTime) { base.update(elapsedTime); if (mMouseDown && mDragingCallback != null) { mDragingCallback(); } if (mMoveSpeed > 0.0f) { // 只有鼠标未按下时才衰减速度 if (!mMouseDown) { mMoveSpeed = lerp(mMoveSpeed, 0.0f, elapsedTime * 5.0f, 0.01f); } Vector3 curPosition = getPosition(); curPosition += mMoveNormal * mMoveSpeed * mMoveSpeedScale * elapsedTime; // 获得第一个带widget的父节点的rect UIRect rect = WidgetUtility.findParentRect(mObject); Vector2 parentWidgetSize = WidgetUtility.getRectSize(rect); // 计算父节点的世界缩放 Vector3 worldScale = getMatrixScale(mTransform.parent.localToWorldMatrix); txUIObject root = mLayout.isNGUI() ? mLayoutManager.getNGUIRoot() : mLayoutManager.getUGUIRoot(); Vector3 uiRootScale = root.getTransform().localScale; Vector2 parentScale = new Vector2(worldScale.x / uiRootScale.x, worldScale.y / uiRootScale.y); // 计算移动的位置范围 Vector2 minPos = new Vector2(parentWidgetSize.x / 2.0f * mMinPos.x, parentWidgetSize.y / 2.0f * mMinPos.y); Vector2 maxPos = new Vector2(parentWidgetSize.x / 2.0f * mMaxPos.x, parentWidgetSize.y / 2.0f * mMaxPos.y); Vector2 thisSize = getWindowSize(true); float minX = (minPos.x - thisSize.x / 2.0f) / parentScale.x; float maxX = (maxPos.x + thisSize.x / 2.0f) / parentScale.x; float minY = (minPos.y - thisSize.y / 2.0f) / parentScale.y; float maxY = (maxPos.y + thisSize.y / 2.0f) / parentScale.y; if (mDragDirection == DRAG_DIRECTION.DD_HORIZONTAL || mDragDirection == DRAG_DIRECTION.DD_FREE) { // 有可以滑动范围时需要限定在一定范围 if (minX <= maxX) { clamp(ref curPosition.x, minX, maxX); } // 不能滑动时,固定位置 else { curPosition.x = getPosition().x; } } if (mDragDirection == DRAG_DIRECTION.DD_VERTICAL || mDragDirection == DRAG_DIRECTION.DD_FREE) { // 有可以滑动范围时需要限定在一定范围 if (minY <= maxY) { clamp(ref curPosition.y, minY, maxY); } // 不能滑动时,固定位置 else { curPosition.y = getPosition().y; } } setLocalPosition(curPosition); } }
// 停靠父节点的指定边界,并且大小不改变,0,1,2,3表示左上右下 protected void setToPaddingParentSide(NEAR_SIDE side) { UIRect parentRect = WidgetUtility.findParentRect(gameObject); if (parentRect == null) { Vector3[] sides = getSides(null); for (int i = 0; i < 4; ++i) { mAnchorPoint[i].setRelative(0.0f); if (i == 0 || i == 2) { mAnchorPoint[i].setAbsolute(sides[i].x); } else { mAnchorPoint[i].setAbsolute(sides[i].y); } } } else { GameObject parent = parentRect.gameObject; Vector3[] sides = getSides(parent); Vector3[] parentSides = WidgetUtility.getParentSides(parent); // 相对于左右边界 if (side == NEAR_SIDE.NS_LEFT || side == NEAR_SIDE.NS_RIGHT) { for (int i = 0; i < 4; ++i) { if (i == 0 || i == 2) { mAnchorPoint[i].setRelative((side == NEAR_SIDE.NS_LEFT) ? -1.0f : 1.0f); mAnchorPoint[i].setAbsolute(sides[i].x - parentSides[(int)side].x); } else { mAnchorPoint[i].setRelative(0.0f); mAnchorPoint[i].setAbsolute(sides[i].y); } } } // 相对于上下边界 else if (side == NEAR_SIDE.NS_TOP || side == NEAR_SIDE.NS_BOTTOM) { for (int i = 0; i < 4; ++i) { if (i == 0 || i == 2) { mAnchorPoint[i].setRelative(0.0f); mAnchorPoint[i].setAbsolute(sides[i].x); } else { mAnchorPoint[i].setRelative((side == NEAR_SIDE.NS_TOP) ? 1.0f : -1.0f); mAnchorPoint[i].setAbsolute(sides[i].y - parentSides[(int)side].y); } } } } }
//------------------------------------------------------------------------------------------------------------------------------------------------ // 将锚点设置到距离相对于父节点最近的边,并且各边界到父节点对应边界的距离固定不变 protected void setToNearParentSides() { UIRect parentRect = WidgetUtility.findParentRect(gameObject); if (parentRect == null) { Vector3[] sides = getSides(null); for (int i = 0; i < 4; ++i) { mAnchorPoint[i].setRelative(0.0f); if (i == 0 || i == 2) { mAnchorPoint[i].setAbsolute(MathUtility.getLength(sides[i])); } else if (i == 1 || i == 3) { mAnchorPoint[i].setAbsolute(MathUtility.getLength(sides[i])); } } return; } else { GameObject parent = parentRect.gameObject; Vector3[] sides = getSides(parent); Vector3[] parentSides = WidgetUtility.getParentSides(parent); for (int i = 0; i < 4; ++i) { if (i == 0 || i == 2) { float relativeLeft = sides[i].x - parentSides[0].x; float relativeCenter = sides[i].x; float relativeRight = sides[i].x - parentSides[2].x; float disToLeft = Mathf.Abs(relativeLeft); float disToCenter = Mathf.Abs(relativeCenter); float disToRight = Mathf.Abs(relativeRight); // 靠近左边 if (disToLeft < disToCenter && disToLeft < disToRight) { mAnchorPoint[i].setRelative(-1.0f); mAnchorPoint[i].setAbsolute(relativeLeft); } // 靠近右边 else if (disToRight < disToLeft && disToRight < disToCenter) { mAnchorPoint[i].setRelative(1.0f); mAnchorPoint[i].setAbsolute(relativeRight); } // 靠近中心 else { mAnchorPoint[i].setRelative(0.0f); mAnchorPoint[i].setAbsolute(relativeCenter); } } else if (i == 1 || i == 3) { float relativeTop = sides[i].y - parentSides[1].y; float relativeCenter = sides[i].y; float relativeBottom = sides[i].y - parentSides[3].y; float disToTop = Mathf.Abs(relativeTop); float disToCenter = Mathf.Abs(relativeCenter); float disToBottom = Mathf.Abs(relativeBottom); // 靠近顶部 if (disToTop < disToCenter && disToTop < disToBottom) { mAnchorPoint[i].setRelative(1.0f); mAnchorPoint[i].setAbsolute(relativeTop); } // 靠近底部 else if (disToBottom < disToTop && disToBottom < disToCenter) { mAnchorPoint[i].setRelative(-1.0f); mAnchorPoint[i].setAbsolute(relativeBottom); } // 靠近中心 else { mAnchorPoint[i].setRelative(0.0f); mAnchorPoint[i].setAbsolute(relativeCenter); } } } } }
//------------------------------------------------------------------------------------------------------------------------------------------------ protected void updateRect(bool force = false) { if (mRoot == null || !force && !mDirty) { return; } mDirty = false; mWidthScale = mHorizontalScale; mHeightScale = mVerticalScale; if (mKeepAspect) { if (mAspectBase == ASPECT_BASE.AB_USE_HEIGHT_SCALE) { mWidthScale = mVerticalScale; } else if (mAspectBase == ASPECT_BASE.AB_USE_WIDTH_SCALE) { mHeightScale = mHorizontalScale; } } float thisWidth = 0.0f; float thisHeight = 0.0f; UIWidget thisWidget = WidgetUtility.getGameObjectWidget(gameObject); if (thisWidget != null) { thisWidth = mOriginWidth * mWidthScale; thisHeight = mOriginHeight * mHeightScale; thisWidget.width = (int)(thisWidth + 0.5f); thisWidget.height = (int)(thisHeight + 0.5f); } if (mPadding == PADDING_STYLE.PS_NONE) { mPosXScale = mWidthScale; mPosYScale = mHeightScale; gameObject.transform.localPosition = new Vector3(mOriginPos.x * mPosXScale, mOriginPos.y * mPosYScale, mOriginPos.z); } else { // 只有在刷新时才能确定父节点,所以父节点需要实时获取 UIRect parentRect = WidgetUtility.findParentRect(gameObject); Vector2 parentSize = WidgetUtility.getRectSize(parentRect); // hori为-1表示窗口坐标在父窗口的左侧边界上,为1表示在右侧边界上 if (mPadding == PADDING_STYLE.PS_LEFT || mPadding == PADDING_STYLE.PS_LEFT_BOTTOM || mPadding == PADDING_STYLE.PS_LEFT_TOP) { mHorizontalRelativePos = -(parentSize.x - thisWidth) / (parentSize.x); } else if (mPadding == PADDING_STYLE.PS_RIGHT || mPadding == PADDING_STYLE.PS_RIGHT_BOTTOM || mPadding == PADDING_STYLE.PS_RIGHT_TOP) { mHorizontalRelativePos = (parentSize.x - thisWidth) / (parentSize.x); } else if (mPadding != PADDING_STYLE.PS_CUSTOM_VALUE) { mHorizontalRelativePos = mOriginPos.x / (parentSize.x / 2.0f); } if (mPadding == PADDING_STYLE.PS_TOP || mPadding == PADDING_STYLE.PS_LEFT_TOP || mPadding == PADDING_STYLE.PS_RIGHT_TOP) { mVerticalRelativePos = (parentSize.y - thisHeight) / (parentSize.y); } else if (mPadding == PADDING_STYLE.PS_BOTTOM || mPadding == PADDING_STYLE.PS_LEFT_BOTTOM || mPadding == PADDING_STYLE.PS_RIGHT_BOTTOM) { mVerticalRelativePos = -(parentSize.y - thisHeight) / (parentSize.y); } else if (mPadding != PADDING_STYLE.PS_CUSTOM_VALUE) { mVerticalRelativePos = mOriginPos.y / (parentSize.y / 2.0f); } Vector3 pos = mOriginPos; pos.x = mHorizontalRelativePos * (parentSize.x / 2.0f); pos.y = mVerticalRelativePos * (parentSize.y / 2.0f); gameObject.transform.localPosition = pos; } // 如果有UIGrid组件,则需要调整UIGrid中的排列间隔 UIGrid grid = gameObject.GetComponent <UIGrid>(); if (gameObject.GetComponent <UIGrid>() != null) { grid.cellHeight *= mHeightScale; grid.cellWidth *= mWidthScale; } }