NGUI深入理解-----------------UIAnchor

总览: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;

确定好Rect后,UIAnchor就结合Rect和Side来计算坐标

		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;		

RunOnlyOnce:如果激活了该选项,应用启动后,位置计算好后,UIAnchor会自动Destroy

if (runOnlyOnce && Application.isPlaying) Destroy(this);
这样可以提高性能,但只能用于禁止不动的UI,对于需要动态调整位置的UI,不能选择该项。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值