Unity UGUI ScrollRect 滑动显示左右箭头

目录

一、前言

二、效果 

三、代码解析

EnhancedScrollRect.cs 解析

Start 方法

HandleArrowVisibility 方法

EnhancedScrollRectEditor.cs 解析

OnEnable 方法

OnInspectorGUI 方法

四、完整代码

EnhancedScrollRect.cs

EnhancedScrollRectEditor.cs

五、总结


Demo链接: 

https://download.csdn.net/download/qq_41973169/89428682icon-default.png?t=N7T8https://download.csdn.net/download/qq_41973169/89428682

一、前言

Unity版本:2022.3.x

在Unity游戏开发中,ScrollRect是一个常用的UI组件,用于实现可滚动的内容区域。然而,默认的ScrollRect组件并不提供对内容边缘的指示功能,例如在内容可以向左或向右继续滚动时显示箭头。为了解决这个问题,我们扩展了ScrollRect组件,增加了两个箭头指示器(leftArrow和rightArrow),用于提示用户当前内容是否可以继续滚动。这两个脚本分别是EnhancedScrollRect.csEnhancedScrollRectEditor.cs

二、效果 

三、代码解析

EnhancedScrollRect.cs 解析

Start 方法

Start方法中,我们首先调用了基类的Start方法,然后添加了一个监听器,当ScrollRect的值改变时触发HandleArrowVisibility方法。接着,我们检查内容是否有ContentSizeFitter组件,如果有的话,我们强制立即重建布局以确保内容的尺寸正确。最后,我们手动调用一次HandleArrowVisibility方法,以初始化箭头的可见性。

protected override void Start()
{
    base.Start();
    onValueChanged.AddListener(HandleArrowVisibility);

    var contentSizeFitter = content.GetComponent<ContentSizeFitter>();
    if (!contentSizeFitter.IsUnityNull())
    {
        LayoutRebuilder.ForceRebuildLayoutImmediate(content);
    }

    HandleArrowVisibility(new Vector2());
}

HandleArrowVisibility 方法

HandleArrowVisibility方法主要用于根据内容的位置来更新箭头的可见性。首先,我们检查各种关键组件是否为null,如果有任何一个为null,则直接返回。然后,我们计算内容的起始位置和结束位置,并根据这些位置判断是否应该显示左右箭头。

private void HandleArrowVisibility(Vector2 position)
{
    if (content.IsUnityNull() || viewport.IsUnityNull() || leftArrow.IsUnityNull() || rightArrow.IsUnityNull())
    {
        return;
    }

    var contentStart = content.anchoredPosition.x;
    var contentEnd = contentStart + content.rect.width - viewport.rect.width;
    leftArrow.gameObject.SetActive(contentStart < -1.0f);
    rightArrow.gameObject.SetActive(contentEnd > 1.0f);
}

EnhancedScrollRectEditor.cs 解析

OnEnable 方法

OnEnable方法中,我们首先调用基类的OnEnable方法,然后使用serializedObject.FindProperty方法查找leftArrowrightArrow属性,并将结果存储在相应的变量中。

protected override void OnEnable()
{
    base.OnEnable();
    _leftArrow = serializedObject.FindProperty("leftArrow");
    _rightArrow = serializedObject.FindProperty("rightArrow");
}

OnInspectorGUI 方法

OnInspectorGUI方法中,我们首先调用基类的OnInspectorGUI方法,然后更新序列化对象的状态。接着,我们使用EditorGUILayout.PropertyField方法绘制leftArrowrightArrow属性的编辑字段。最后,我们应用修改并在检测到GUI发生变化时,将目标对象标记为脏,以确保更改被保存。

public override void OnInspectorGUI()
{
    base.OnInspectorGUI();

    serializedObject.Update();

    EditorGUILayout.PropertyField(_leftArrow);
    EditorGUILayout.PropertyField(_rightArrow);

    serializedObject.ApplyModifiedProperties();
    if (GUI.changed)
    {
        EditorUtility.SetDirty(target);
    }
}

四、完整代码

EnhancedScrollRect.cs

using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;

public class EnhancedScrollRect : ScrollRect
{
    [SerializeField] private RectTransform leftArrow;

    [SerializeField] private RectTransform rightArrow;

    protected override void Start()
    {
        base.Start();
        onValueChanged.AddListener(HandleArrowVisibility);

        var contentSizeFitter = content.GetComponent<ContentSizeFitter>();
        if (!contentSizeFitter.IsUnityNull())
        {
            LayoutRebuilder.ForceRebuildLayoutImmediate(content);
        }

        HandleArrowVisibility(new Vector2());
    }

    private void HandleArrowVisibility(Vector2 position)
    {
        if (content.IsUnityNull() || viewport.IsUnityNull() || leftArrow.IsUnityNull() || rightArrow.IsUnityNull())
        {
            return;
        }

        var contentStart = content.anchoredPosition.x;
        var contentEnd = contentStart + content.rect.width - viewport.rect.width;
        leftArrow.gameObject.SetActive(contentStart < -1.0f);
        rightArrow.gameObject.SetActive(contentEnd > 1.0f);
    }
}

EnhancedScrollRectEditor.cs

using UnityEditor;
using UnityEditor.UI;
using UnityEngine;

[CustomEditor(typeof(EnhancedScrollRect), true)]
[CanEditMultipleObjects]
public class EnhancedScrollRectEditor : ScrollRectEditor
{
    private SerializedProperty _leftArrow;

    private SerializedProperty _rightArrow;

    protected override void OnEnable()
    {
        base.OnEnable();
        _leftArrow = serializedObject.FindProperty("leftArrow");
        _rightArrow = serializedObject.FindProperty("rightArrow");
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        serializedObject.Update();

        EditorGUILayout.PropertyField(_leftArrow);
        EditorGUILayout.PropertyField(_rightArrow);

        serializedObject.ApplyModifiedProperties();
        if (GUI.changed)
        {
            EditorUtility.SetDirty(target);
        }
    }
}

五、总结

通过这两个脚本,我们扩展了Unity的ScrollRect组件,使其能够根据内容的滚动状态显示左右箭头,提示用户内容可以继续滚动。此外,我们还自定义了编辑器,可以在Inspector窗口中方便地设置左右箭头的引用。这种扩展方法既保留了原有组件的所有功能,又增强了用户体验,是一种推荐的组件扩展方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/706908.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

零碳产业园区建设指南案例

零碳产业园区的建设一直备受广泛关注&#xff0c;特别是在我国碳达峰碳中和的背景下。据不完全统计&#xff0c;目前&#xff0c;全国共有国家级和省级园区2500余家&#xff0c;这些园区在贡献了全国50%工业产出的同时&#xff0c;其CO2排放量也占到了全国排放总量的30%以上。作…

31、shell循环

一、循环 循环&#xff1a;循环是一种重复执行一段代码的结构。只要满足循环的条件&#xff0c;会一直执行这个代码。 循环条件&#xff1a;在一定范围之内&#xff0c;按照指定的次数来执行循环。 循环体&#xff1a;在指定的次数内&#xff0c;执行的命令序列。只要条件满…

谷粒商城实战(035 k8s集群学习1-前置介绍)

Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强 总时长 104:45:00 共408P 此文章包含第339p-第p342的内容 分布式高级篇总结 高可用集群 内容 k8s介绍 为什么使用k8s 组件 master组件 node&#xff08;节点&#xff09;组件 要部…

2.spring cloud gateway 源码编译

spring cloud gateway编译 1.编译 命令 mvn clean compile -U2.报错 报错信息 核心信息 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.1.2:check (checkstyle-validation) on project spring-cloud-gateway-mvc: Failed during …

【复旦邱锡鹏教授《神经网络与深度学习公开课》笔记】神经元和人工神经网络

神经元 生物神经元&#xff1a; 平时处于抑制状态&#xff0c;当接受信息量达到一定程度后进入兴奋状态。 人工神经元&#xff1a; 一个人工神经元大致有两个步骤&#xff1a; 一是收集信息&#xff0c;如上图中 x 1 , ⋯ , x d x_1,\cdots,x_d x1​,⋯,xd​表示神经元可…

Android AOSP定制去掉Google搜索栏

Android AOSP定制去掉Google搜索栏 1.前言&#xff1a; ​ 最近接触了Android系统定制的需求&#xff0c;感觉非常有意思&#xff0c;之前做过Launcher和串口&#xff0c;也自己安装过虚拟机&#xff0c;不过几年没用Linux系统了有点不习惯&#xff0c;Linux命令也不熟悉&…

Flink Sql:四种Join方式详解(基于flink1.15官方文档)

JOINs flink sql主要有四种连接方式&#xff0c;分别是Regular Joins、Interval Joins、Temporal Joins、lookup join 1、Regular Joins&#xff08;常规连接 &#xff09; 这种连接方式和hive sql中的join是一样的&#xff0c;包括inner join&#xff0c;left join&#xff…

【论文阅读】-- 时态合并树状图:时态标量数据的基于拓扑的静态可视化

时态合并树状图&#xff1a;时态标量数据的基于拓扑的静态可视化 摘要1 引言2 相关工作及背景介绍2.1 增广合并树2.2 (增强)合并树的可视化与跟踪2.3 特征跟踪2.4 数据线性化 3 时间合并树状图3.1 映射单个时间步长&#xff1a; R d → R R^d \rightarrow R Rd→R3.2 映射所有时…

Unity 设置窗口置顶超级详解版

目录 前言 一、user32.dll 1.什么是user32.dll 2.如何使用user32.dll 二、句柄Handle 1.句柄 2.句柄的功能 3.拿句柄的方法 三、窗口置顶 1.窗口置顶的方法 2.参数说明 3.使用方法 四、作者的碎碎念 前言 up依旧挑战全网讲解最详细版本~~ 本篇文章讲解的是unity…

基于Springboot的小型超市商品展销系统-计算机毕业设计源码01635

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

anaconda安装pytorch-快速上手99%可以(可以虚拟环境OR不进行虚拟环境)

一、预备工作 先检查自己是否有anaconda 在cmd里面输入conda --version查看 二、在anaconda中创建虚拟环境 1.1 打开Anaconda Prompt 1.2 进行自定义安装python 将其中的自定义地址和版本换成自己想安装的地址和版本 我这里安装的地址是E:\Anaconda\DL,python版本是3.8.3…

循环 -控制语句

循环 循环是什么 重复执行一段代码的结构。只要满足循环的条件&#xff0c;会一直执行这个代码。 循环条件&#xff1a;在一定范围之内&#xff0c;按照指定的次数来执行循环。 循环体&#xff1a;在指定的次数内执行的命令序列。只要条件满足循环体会被一直执行。 循环和…

Windows搭建nacos集群

Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件。相比Eureka功能更加丰富&#xff0c;在国内受欢迎程度较高。 下载地址&#xff1a;Tags alibaba/nacos GitHub 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;8888 解压文件夹 目录说明&am…

FPGA - 滤波器 - FIR滤波器设计

一&#xff0c;数字滤波器 滤波器是一种用来减少或消除干扰的器件&#xff0c;其功能是对输入信号进行过滤处理得到所需的信号。滤波器最常见的用法是对特定频率的频点或该频点以外的频率信号进行有效滤除&#xff0c;从而实现消除干扰、获取某特定频率信号的功能。一种更广泛的…

MyBatis 高级映射与延迟加载(分步查询)的详细内容

1. MyBatis 高级映射与延迟加载&#xff08;分步查询&#xff09;的详细内容 文章目录 1. MyBatis 高级映射与延迟加载&#xff08;分步查询&#xff09;的详细内容2. 准备工作3. 多对一 高级映射3.1 第一种方式&#xff1a;级联属性映射3.2 第二种方式&#xff1a;association…

英格索兰IngsollRang控制器过热维修讲解

【英格索兰IngsollRang控制器维修请关注】 【英格索兰IngsollRang控制器维修】 【英格索兰控制器维修】 一、IngsollRang扭矩枪控制器故障诊断 1. 检查环境温度&#xff1a;首先&#xff0c;确认工作场所的温度是否过高。如果环境温度超过设备规定的工作温度&#xff0c;可能…

刷代码随想录有感(102):动态规划——整数拆分

题干&#xff1a; 代码&#xff1a; class Solution { public:int integerBreak(int n) {vector<int>dp(n 1);dp[0] 0;dp[1] 0;dp[2] 1;for(int i 3; i < n; i){for(int j 1; j < i / 2; j){dp[i] max(dp[i], max((j) * (i - j), j * dp[i - j]));}}return…

JavaScript的数组(一维数组、二维数组、数组常用的方法调用)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

eclipse 老的s2sh(Struts2+Spring+Hibernate) 项目 用import导入直接导致死机(CPU100%)的解决

1、下载Apache Tomcat - Apache Tomcat 8 Software Downloads 图中是8.5.100的版本&#xff0c;下面的设置用的是另一个版本的&#xff0c;其实是一样。 2、先将Server配好&#xff0c;然后再进行导入操作。 2、选择jdk 当然&#xff0c;这里也可以直接“Download and instal…

无公网IP与服务器完成企业微信网页应用开发远程调试详细流程

文章目录 前言1. Windows安装Cpolar2. 创建Cpolar域名3. 创建企业微信应用4. 定义回调本地接口5. 回调和可信域名接口校验6. 设置固定Cpolar域名7. 使用固定域名校验 前言 本文主要介绍如何在企业微信开发者中心通过使用内网穿透工具提供的公网域名成功验证回调本地接口服务! …