public void updateRect(bool force = false) { // 是否为编辑器手动预览操作,手动预览不需要启动游戏 #if UNITY_EDITOR bool preview = !EditorApplication.isPlaying; #else bool preview = false; #endif // 如果是第一次更新,则需要获取原始属性 if (mFirstUpdate || preview) { mScreenScale = UnityUtility.getScreenScale(UnityUtility.getRootSize(preview)); mOriginSize = WidgetUtility.getRectSize(GetComponent <RectTransform>()); mOriginPos = transform.localPosition; mFirstUpdate = false; } if (!preview && !force && !mDirty) { return; } mDirty = false; Vector3 realScale = UnityUtility.adjustScreenScale(mScreenScale, mKeepAspect ? mAspectBase : ASPECT_BASE.NONE); float thisWidth = mOriginSize.x * realScale.x; float thisHeight = mOriginSize.y * realScale.y; MathUtility.checkInt(ref thisWidth, 0.001f); MathUtility.checkInt(ref thisHeight, 0.001f); Vector2 newSize = new Vector2(thisWidth, thisHeight); // 只有在刷新时才能确定父节点,所以父节点需要实时获取 WidgetUtility.setRectSize(GetComponent <RectTransform>(), newSize, mAdjustFont); transform.localPosition = MathUtility.round(MathUtility.multiVector3(mOriginPos, realScale)); }
//------------------------------------------------------------------------------------------------------------------------------------------ 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 }); }
public void init(int renderOrder) { mScript = mLayoutManager.createScript(this); int count = mLayoutScriptCallback.Count; for (int i = 0; i < count; ++i) { mLayoutScriptCallback[i].Invoke(mScript, true); } if (mScript == null) { logError("can not create layout script! id : " + mID); return; } myUIObject parent = mIsScene ? null : mLayoutManager.getUIRoot(); // 初始化布局脚本 mScript.newObject(out mRoot, parent, mName); if (mRoot != null) { // 去除自带的锚点 // 在unity2020中,不知道为什么实例化以后的RectTransform的大小会自动变为窗口大小,为了适配计算正确,这里需要重置一次 RectTransform rectTransform = mRoot.getRectTransform(); Vector3 size = WidgetUtility.getRectSize(rectTransform); rectTransform.anchorMin = Vector2.one * 0.5f; rectTransform.anchorMax = Vector2.one * 0.5f; WidgetUtility.setRectSize(rectTransform, new Vector2(GameDefine.STANDARD_WIDTH, GameDefine.STANDARD_HEIGHT), false); } mRoot.setDestroyImmediately(true); mDefaultLayer = mRoot.getObject().layer; mScript.setRoot(mRoot); mScript.assignWindow(); // assignWindow后设置布局的渲染顺序,这样可以在此处刷新所有窗口的深度 setRenderOrder(renderOrder); // 布局实例化完成,初始化之前,需要调用自适应组件的更新 if (mLayoutManager.isUseAnchor()) { applyAnchor(mRoot.getObject(), true, this); } mAnchorApplied = true; mScript.init(); mScriptInited = true; // 加载完布局后强制隐藏 setVisibleForce(false); #if UNITY_EDITOR mRoot.getUnityComponent <LayoutDebug>().setLayout(this); #endif }
//------------------------------------------------------------------------------------------------------------------------------ protected static void roundRectTransformToInt(RectTransform rectTransform) { if (rectTransform == null) { return; } rectTransform.localPosition = round(rectTransform.localPosition); WidgetUtility.setRectSize(rectTransform, round(WidgetUtility.getRectSize(rectTransform)), false); int childCount = rectTransform.childCount; for (int i = 0; i < childCount; ++i) { roundRectTransformToInt(rectTransform.GetChild(i) as RectTransform); } }
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); } }
//------------------------------------------------------------------------------------------------------------------------------------------------ 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; } }