一、组件功能概述
ViewportConstraint
是一个基于世界坐标的UI边界约束组件,主要功能包括:
- 将UI元素限制在父容器范围内
- 支持自定义内边距(padding)
- 可独立控制水平和垂直方向的约束
二、实现原理
1. 边界计算(世界坐标)
使用GetWorldCorners
方法获取四个顶点的世界坐标
2. 约束逻辑
如果元素左边界超出了容器左边界,则该元素需要往右移:右移距离 = 容器左边界 - 元素左边界将元素向右移动一定距离
三、代码
using System.Collections.Generic;
using UnityEngine;/// <summary>
/// 限制指定元素在显示区域内显示
/// </summary>
public class ViewportConstraint : MonoSingleton<ViewportConstraint>
{string TAG = "[ViewportConstraint]";[Header("容器")]public RectTransform parentContainer;[Header("内边距")]public float padding = 30f;[Header("约束元素")]public List<RectTransform> elements = new List<RectTransform>();[Header("约束方向")]public bool constrainHorizontal = true;public bool constrainVertical = true;public void Refresh(){Debug.Log(TAG + "Refresh");foreach (var target in elements){Vector3[] parentCorners = new Vector3[4];parentContainer.GetWorldCorners(parentCorners);Vector3[] objCorners = new Vector3[4];target.GetWorldCorners(objCorners);if (constrainHorizontal){// 计算显示区域float displayLeft = parentCorners[0].x + padding;float displayRight = parentCorners[2].x - padding;// 计算子物体左右边界float objLeft = objCorners[0].x;float objRight = objCorners[2].x;Vector3 pos = target.position;// 左边越界if (objLeft < displayLeft) pos.x += displayLeft - objLeft;// 右边越界else if (objRight > displayRight) pos.x += displayRight - objRight;target.position = pos;}if(constrainVertical){// 计算显示区域float displayBottom = parentCorners[0].y + padding;float displayTop = parentCorners[1].y - padding;// 计算子物体上下边界float objBottom = objCorners[0].y;float objTop = objCorners[1].y;Vector3 pos = target.position;// 底部越界if (objBottom < displayBottom) pos.y += displayBottom - objBottom;// 顶部越界else if (objTop > displayTop) pos.y += displayTop - objTop;target.position = pos;}}}//注:目标物体须设定为锚点居中。}