总览:NGUI深入理解
UIAnchor用于将某个object定位到空间的某个角落。其中Side为锚点位置,它有上中下左右等9个位置。但这9个位置是相对于谁的呢?或者说是相对于那个Rect的呢?UIAnchor按照下面的顺序来确定这个Rect:
①PanelContainer
②WidgetContainer
③UICamera
当PanelContainer非空,则按照下面的规则来计算Rect
if (panelContainer.clipping == UIDrawCall.Clipping.None) { // Panel has no clipping -- just use the screen's dimensions float ratio = (mRoot != null) ? (float)mRoot.activeHeight / Screen.height * 0.5f : 0.5f; mRect.xMin = -Screen.width * ratio; mRect.yMin = -Screen.height * ratio; mRect.xMax = -mRect.xMin; mRect.yMax = -mRect.yMin; } else { // Panel has clipping -- use it as the mRect Vector4 pos = panelContainer.clipRange; mRect.x = pos.x - (pos.z * 0.5f); mRect.y = pos.y - (pos.w * 0.5f); mRect.width = pos.z; mRect.height = pos.w; }当Panel不是软剪切Panle时,Rect基本就是Scene.width和Scene.heitht组成的矩形,而当panel为剪切Panel时,则Rect为剪切窗口大小。
当WidgetContrainer非空,则按羡慕的规则来计算Rect
Transform t = widgetContainer.cachedTransform; Vector3 ls = t.localScale; Vector3 lp = t.localPosition; Vector3 size = widgetContainer.relativeSize; Vector3 offset = widgetContainer.pivotOffset; offset.y -= 1f; offset.x *= (widgetContainer.relativeSize.x * ls.x); offset.y *= (widgetContainer.relativeSize.y * ls.y); mRect.x = lp.x + offset.x; mRect.y = lp.y + offset.y; mRect.width = size.x * ls.x; mRect.height = size.y * ls.y;这个rect基本就等于widget缩放后的大小了。
当上面两个都为空时,就取相机的大小
useCamera = true; mRect = uiCamera.pixelRect;
float cx = (mRect.xMin + mRect.xMax) * 0.5f; float cy = (mRect.yMin + mRect.yMax) * 0.5f; Vector3 v = new Vector3(cx, cy, 0f); if (side != Side.Center) { if (side == Side.Right || side == Side.TopRight || side == Side.BottomRight) v.x = mRect.xMax; else if (side == Side.Top || side == Side.Center || side == Side.Bottom) v.x = cx; else v.x = mRect.xMin; if (side == Side.Top || side == Side.TopRight || side == Side.TopLeft) v.y = mRect.yMax; else if (side == Side.Left || side == Side.Center || side == Side.Right) v.y = cy; else v.y = mRect.yMin; } float width = mRect.width; float height = mRect.height; v.x += relativeOffset.x * width; v.y += relativeOffset.y * height; if (useCamera) { if (uiCamera.orthographic) { v.x = Mathf.Round(v.x); v.y = Mathf.Round(v.y); if (halfPixelOffset && mNeedsHalfPixelOffset) { v.x -= 0.5f; v.y += 0.5f; } } v.z = uiCamera.WorldToScreenPoint(mTrans.position).z; v = uiCamera.ScreenToWorldPoint(v); } else { v.x = Mathf.Round(v.x); v.y = Mathf.Round(v.y); if (panelContainer != null) { v = panelContainer.cachedTransform.TransformPoint(v); } else if (widgetContainer != null) { Transform t = widgetContainer.cachedTransform.parent; if (t != null) v = t.TransformPoint(v); } v.z = mTrans.position.z; } // Wrapped in an 'if' so the scene doesn't get marked as 'edited' every frame if (mTrans.position != v) mTrans.position = v;
if (runOnlyOnce && Application.isPlaying) Destroy(this);这样可以提高性能,但只能用于禁止不动的UI,对于需要动态调整位置的UI,不能选择该项。