/// <summary>
/// 窗口组件自适应
/// parentRect作为窗口边界,规定允许边界内对齐移动
/// targetRect最为对齐目标,锚点分为上下对齐两种方式,根据parentRect上下边界自动计算
/// </summary>
public class WindowAdapter : MonoBehaviour
{
[Header("父物体")]
[SerializeField]
private RectTransform parentRect;
[Header("对齐锚点")]
[SerializeField]
private AdaptionPivot adaptionPivot = AdaptionPivot.Bottom;
private RectTransform rectTrans
{
get { return transform as RectTransform;}
}
[SerializeField]
private AdaptionType adaptionType = AdaptionType.Both;
[SerializeField] private Vector2 alignOffset = Vector2.zero;
private Vector2 targetPos = Vector2.zero;
#region private
private void Awake()
{
rectTrans.anchorMin = Vector2.zero;
rectTrans.anchorMax = Vector2.zero;
switch (adaptionPivot)
{
case AdaptionPivot.Top:
rectTrans.pivot = new Vector2(0.5f,1f);
break;
case AdaptionPivot.Middle:
rectTrans.pivot = new Vector2(0.5f,0.5f);
break;
case AdaptionPivot.Bottom:
rectTrans.pivot = new Vector2(0.5f,0f);
break;
}
}
private void Adaption()
{
switch (adaptionType)
{
case AdaptionType.Horizontal:
HorAdaption();
break;
case AdaptionType.Vertical:
VerAdaption();
break;
default:
HorAdaption();
VerAdaption();
break;
}
}
private void HorAdaption()
{
float rectHalf = rectTrans.rect.width / 2;
float currentPosX = targetPos.x + rectHalf + alignOffset.x;
if (currentPosX > parentRect.rect.width)
{
float x = parentRect.rect.width - rectHalf;
rectTrans.anchoredPosition = new Vector2(x,rectTrans.anchoredPosition.y);
}else if (targetPos.x + alignOffset.x - rectHalf < 0)
{
rectTrans.anchoredPosition = new Vector2(rectHalf,rectTrans.anchoredPosition.y);
}
else
{
rectTrans.anchoredPosition = new Vector2(targetPos.x + alignOffset.x,rectTrans.anchoredPosition.y);
}
}
private void VerAdaption()
{
float topAnc = 0;
float bottomAnc = 0;
if (rectTrans.localScale.y == 1)
{
topAnc = rectTrans.rect.height * (1 - rectTrans.pivot.y);
bottomAnc = rectTrans.rect.height * rectTrans.pivot.y;
}
else
{
topAnc = rectTrans.rect.height * rectTrans.pivot.y;
bottomAnc = rectTrans.rect.height * (1 - rectTrans.pivot.y);
}
float topPosy = targetPos.y + topAnc + alignOffset.y;
float bottomPosy = targetPos.y - bottomAnc + alignOffset.y;
if (topPosy > parentRect.rect.height)
{
float y = parentRect.rect.height - topAnc;
rectTrans.anchoredPosition = new Vector2(rectTrans.anchoredPosition.x,y);
}else if (bottomPosy < 0)
{
rectTrans.anchoredPosition = new Vector2(rectTrans.anchoredPosition.x,bottomAnc);
}
else
{
rectTrans.anchoredPosition = new Vector2(rectTrans.anchoredPosition.x,targetPos.y + alignOffset.y);
}
}
#endregion
#region public
/// <summary>
/// 自动对齐
/// </summary>
public void AlignWithTarget(RectTransform targetRect)
{
targetPos = Vector2.zero;
if (Camera.main == null || parentRect == null || targetRect == null)
{
Debug.LogError("GetAnchorPos error");
return;
}
var screenPoint = RectTransformUtility.WorldToScreenPoint(Global.UICamera, targetRect.position);
RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRect, screenPoint, Global.UICamera, out targetPos);
Adaption();
}
#endregion
}
public enum AdaptionType
{
Both = 0,
Horizontal = 1,
Vertical = 2,
}
public enum AdaptionPivot
{
Top = 0,
Middle = 1,
Bottom = 2,
}