Unity_NGUI锚点Anchor自适应

Unity中 NGUI插件十分方便利用Anchor属性, 可以做出屏幕的适应,比如做个小地图一直在右上角,做个血量条一直在左上角。做个技能栏一直在屏幕正下方。其实在Unity 里的UGUI也可以很容易实现,但是呢,没有NGUI集成的多,不大方便, 

在Unity中 修改Canvas 中的属性

 

这个是调整 sprite 的scale 不会被拉伸,然后再 调下Rect Transform中的锚点 Anchors 为右上角

小地图就是右上角, 技能栏就是 下方,然后再细调下Pivot


 就可以做到自适应了,这个是UGUI 的设置

NGUI 呢 也是 修改Anchor的 属性


左上 就 是 血量,  右上也 只需要设置 Left Right 为Right,即可。

小地图 左右对应是center, 上下对应是下方;   Anchors 锚点--就是 边框距离 外部的相对位置。 类似css中margin属性 不过margin 对应的是元素, 而NGUI中Anchor的Unified 类型对应的是整个屏幕,而高级 Advence里,可以有4个targer对应。

而具体的算法在 NGUIMath里面, AdjustWidget这个方法里

	/// <summary>
	/// Adjust the widget's rectangle based on the specified modifier values.
	/// </summary>

	static public void AdjustWidget (UIWidget w, float left, float bottom, float right, float top,
		int minWidth, int minHeight, int maxWidth, int maxHeight)
	{
		Vector2 piv = w.pivotOffset;
		Transform t = w.cachedTransform;
		Quaternion rot = t.localRotation;

		// We should be working with whole integers
		int iLeft = Mathf.FloorToInt(left + 0.5f);
		int iBottom = Mathf.FloorToInt(bottom + 0.5f);
		int iRight = Mathf.FloorToInt(right + 0.5f);
		int iTop = Mathf.FloorToInt(top + 0.5f);

		// Centered pivot should mean having to perform even number adjustments
		if (piv.x == 0.5f && (iLeft == 0 || iRight == 0))
		{
			iLeft = ((iLeft >> 1) << 1);
			iRight = ((iRight >> 1) << 1);
		}

		if (piv.y == 0.5f && (iBottom == 0 || iTop == 0))
		{
			iBottom = ((iBottom >> 1) << 1);
			iTop = ((iTop >> 1) << 1);
		}

		// The widget's position (pivot point) uses a different coordinate system than
		// other corners. This is a source of major PITA, and results in a lot of extra math.
		Vector3 rotatedTL = rot * new Vector3(iLeft, iTop);
		Vector3 rotatedTR = rot * new Vector3(iRight, iTop);
		Vector3 rotatedBL = rot * new Vector3(iLeft, iBottom);
		Vector3 rotatedBR = rot * new Vector3(iRight, iBottom);
		Vector3 rotatedL = rot * new Vector3(iLeft, 0f);
		Vector3 rotatedR = rot * new Vector3(iRight, 0f);
		Vector3 rotatedT = rot * new Vector3(0f, iTop);
		Vector3 rotatedB = rot * new Vector3(0f, iBottom);

		Vector3 offset = Vector3.zero;

		if (piv.x == 0f && piv.y == 1f)
		{
			offset.x = rotatedTL.x;
			offset.y = rotatedTL.y;
		}
		else if (piv.x == 1f && piv.y == 0f)
		{
			offset.x = rotatedBR.x;
			offset.y = rotatedBR.y;
		}
		else if (piv.x == 0f && piv.y == 0f)
		{
			offset.x = rotatedBL.x;
			offset.y = rotatedBL.y;
		}
		else if (piv.x == 1f && piv.y == 1f)
		{
			offset.x = rotatedTR.x;
			offset.y = rotatedTR.y;
		}
		else if (piv.x == 0f && piv.y == 0.5f)
		{
			offset.x = rotatedL.x + (rotatedT.x + rotatedB.x) * 0.5f;
			offset.y = rotatedL.y + (rotatedT.y + rotatedB.y) * 0.5f;
		}
		else if (piv.x == 1f && piv.y == 0.5f)
		{
			offset.x = rotatedR.x + (rotatedT.x + rotatedB.x) * 0.5f;
			offset.y = rotatedR.y + (rotatedT.y + rotatedB.y) * 0.5f;
		}
		else if (piv.x == 0.5f && piv.y == 1f)
		{
			offset.x = rotatedT.x + (rotatedL.x + rotatedR.x) * 0.5f;
			offset.y = rotatedT.y + (rotatedL.y + rotatedR.y) * 0.5f;
		}
		else if (piv.x == 0.5f && piv.y == 0f)
		{
			offset.x = rotatedB.x + (rotatedL.x + rotatedR.x) * 0.5f;
			offset.y = rotatedB.y + (rotatedL.y + rotatedR.y) * 0.5f;
		}
		else if (piv.x == 0.5f && piv.y == 0.5f)
		{
			offset.x = (rotatedL.x + rotatedR.x + rotatedT.x + rotatedB.x) * 0.5f;
			offset.y = (rotatedT.y + rotatedB.y + rotatedL.y + rotatedR.y) * 0.5f;
		}

		minWidth = Mathf.Max(minWidth, w.minWidth);
		minHeight = Mathf.Max(minHeight, w.minHeight);

		// Calculate the widget's width and height after the requested adjustments
		int finalWidth = w.width + iRight - iLeft;
		int finalHeight = w.height + iTop - iBottom;

		// Now it's time to constrain the width and height so that they can't go below min values
		Vector3 constraint = Vector3.zero;

		int limitWidth = finalWidth;
		if (finalWidth < minWidth) limitWidth = minWidth;
		else if (finalWidth > maxWidth) limitWidth = maxWidth;

		if (finalWidth != limitWidth)
		{
			if (iLeft != 0) constraint.x -= Mathf.Lerp(limitWidth - finalWidth, 0f, piv.x);
			else constraint.x += Mathf.Lerp(0f, limitWidth - finalWidth, piv.x);
			finalWidth = limitWidth;
		}

		int limitHeight = finalHeight;
		if (finalHeight < minHeight) limitHeight = minHeight;
		else if (finalHeight > maxHeight) limitHeight = maxHeight;

		if (finalHeight != limitHeight)
		{
			if (iBottom != 0) constraint.y -= Mathf.Lerp(limitHeight - finalHeight, 0f, piv.y);
			else constraint.y += Mathf.Lerp(0f, limitHeight - finalHeight, piv.y);
			finalHeight = limitHeight;
		}

		// Centered pivot requires power-of-two dimensions
		if (piv.x == 0.5f) finalWidth  = ((finalWidth  >> 1) << 1);
		if (piv.y == 0.5f) finalHeight = ((finalHeight >> 1) << 1);

		// Update the position, width and height
		Vector3 pos = t.localPosition + offset + rot * constraint;
		t.localPosition = pos;
		w.SetDimensions(finalWidth, finalHeight);

		// If the widget is anchored, we should update the anchors as well
		if (w.isAnchored)
		{
			t = t.parent;
			float x = pos.x - piv.x * finalWidth;
			float y = pos.y - piv.y * finalHeight;

			if (w.leftAnchor.target) w.leftAnchor.SetHorizontal(t, x);
			if (w.rightAnchor.target) w.rightAnchor.SetHorizontal(t, x + finalWidth);
			if (w.bottomAnchor.target) w.bottomAnchor.SetVertical(t, y);
			if (w.topAnchor.target) w.topAnchor.SetVertical(t, y + finalHeight);
		}

猜你喜欢

转载自blog.csdn.net/qq2512667/article/details/80978501
今日推荐