当前位置: 首页 > news >正文

Unity ViewportConstraint

一、组件功能概述

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;
            }
        }
    }
    //注:目标物体须设定为锚点居中。

}

相关文章:

  • 蓝桥杯 web 新鲜的蔬菜(css3)
  • javaweb自用笔记:Maven分模块设计与开发、Maven继承与聚合、Maven私服
  • 什么是数据
  • LogicFlow-前端流程图开发
  • 使用成员函数指针数组简化C++类中的操作
  • WebGL数学手记:矩阵基础
  • 安防监控/视频集中存储平台EasyCVR赋能养老院:构建多维度智能安防新生态
  • flink 增量快照同步文件引用关系和恢复分析
  • 中国金属通报杂志社中国金属通报编辑部2024年第12期目录
  • 一个开源的 VS Code 大模型聊天插件:Light-at
  • 搭建docker registry私服,并且支持https推送
  • 使用人工智能大模型腾讯元宝,如何快速编写活动记录?
  • ZKmall开源商城服务端验证:Jakarta Validation 详解
  • C++学习day7
  • Linux学习笔记(2) 命令基础:从概念到实践(期末,期中复习笔记全)
  • 从零开始学Python游戏编程13-整数3
  • 【LangChain Agent 】详解,构建自主决策的 LLM 应用
  • Django信号使用完全指南示例
  • 视频插帧EMAVFI:extracting motion and appearance via inter-frame attention for video
  • 虚拟世界的AI魔法:AIGC引领元宇宙创作革命
  • 沧州做网站哪家好/什么搜索引擎搜索最全
  • 建筑网站 法人签字/百度风云榜明星
  • 网站模板前台后台/湖北seo推广
  • 网站用什么技术实现/企业网站模板源码
  • 常设中国建设工程法律论坛网站/广告服务平台
  • 网站系统建设与管理/百度惠生活商家入驻