Unity UGUI ScrollRect 滑动显示左右箭头

news2025/1/11 9:56:04

目录

一、前言

二、效果 

三、代码解析

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窗口中方便地设置左右箭头的引用。这种扩展方法既保留了原有组件的所有功能,又增强了用户体验,是一种推荐的组件扩展方式。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ollama系统更改模型存放位置

1.windows 设置完后可以在cmd中检查一下&#xff1a;echo %ollama_models% 2.linux 首先第一步&#xff1a;cd /etc/systemd/system/ 打开配置文件vim ollama.service 第二步&#xff1a;目录下的environment里面分号隔开添加OLLAMA_MODELS环境变量 第三步&#xff1a;source …

单张图像扩散模型(Single Image DIffusion Model)

论文&#xff1a;SinDDM: A Single Image Denoising Diffusion Model&#xff0c; ICML 2023 去噪扩散模型&#xff08;DDM&#xff09;在图像生成、编辑和恢复方面带来了惊人的性能飞跃。然而&#xff0c;现有DDM使用非常大的数据集进行训练。在这里&#xff0c;介绍一个用于…

tkinter文本对齐方式

tkinter文本对齐方式 文本对齐方式效果代码 文本对齐方式 左对齐&#xff08;left&#xff09;&#xff1a;默认对齐方式&#xff0c;文本从左边界开始。右对齐&#xff08;right&#xff09;&#xff1a;文本从右边界开始。居中对齐&#xff08;center&#xff09;&#xff1…

代码生成-CodeGeeX2本地部署体验

一 CodeGeeX2介绍&#xff1a; CodeGeeX2 是多语言代码生成模型 CodeGeeX (KDD’23) 的第二代模型。不同于一代 CodeGeeX&#xff08;完全在国产华为昇腾芯片平台训练&#xff09; &#xff0c;CodeGeeX2 是基于 ChatGLM2 架构加入代码预训练实现&#xff0c;得益于 ChatGLM2 的…

深圳尚水智能IPO迷局:创始人不看好公司发展退出,比亚迪加入

近日&#xff0c;上海证券交易所披露的信息显示&#xff0c;深圳市尚水智能股份有限公司&#xff08;下称“尚水智能”&#xff09;及其保荐人民生证券撤回上市申请文件。因此&#xff0c;上海证券交易所决定终止对其首次公开发行股票并在科创板上市的审核。 据贝多财经了解&am…

前端技术回顾系列 10|TS 泛型在类和接口中的应用

在微信中阅读,关注公众号:CodeFit。 创作不易,如果你觉得这篇文章对您有帮助,请不要忘了 点赞、分享 和 关注 我的公众号:CodeFit,为我的持续创作提供动力。 上文回顾:约束泛型(Generic Constraints) 上一篇文章我们回顾了 泛型 在 TypeScript 中的高级用法 —— 泛型…

为什么需要负样本

假如我们只有正样本&#xff0c;模型在最开始训练的时候都是错误的&#xff0c;随着模型的迭代&#xff0c;准确率逐渐从0到1&#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…

Linux下的GPIO编程

目录 一、前言 二、sysfs方式 1、sysfs简介 2、基本目录结构 3、编号计算 4、sysfs方式控制GPIO 三、libgpiod库 1、libgpiod库简介 2、API函数 四、LED灯编程 一、前言 在Linux下&#xff0c;我们通常使用 sysfs 和 libgpiod库 两种方式进行控制GPIO&#xff0c;目前…

CP AUTOSAR标准中文文档链接索引(更新中)

AUTOSAR标准的核心组件包括通信、诊断、安全等&#xff0c;这些组件通过模块化结构进行组织。系统被划分为多个模块&#xff0c;每个模块负责特定的功能。模块之间通过接口进行通信&#xff0c;接口定义了模块之间的交互规则。AUTOSAR标准支持模块的配置&#xff0c;可以根据不…

影响数字本振信噪比的因素

2048 点 -66 4096 点-72 8192 点-77 16384 点-84

udp协议下的socket函数

目录 1.网络协议 2.网络字节序 3.socket编译接口 4.sockaddr结构体 5.模拟实现 1.socket函数 2.bind函数&#xff08;绑定&#xff09; 1.讲解 1.如何快速的将 整数ip<->字符串 2.ip地址的注意事项 3.端口号的注意事项 3.recvfrom函数 4.sendto函数 5.代码呈…

yolov5-7.0更改resnet主干网络

参考链接 ClearML教程:https://blog.csdn.net/qq_40243750/article/details/126445671 b站教学视频&#xff1a;https://www.bilibili.com/video/BV1Mx4y1A7jy/spm_id_from333.788&vd_sourceb52b79abfe565901e6969da2a1191407 开始 github地址:https://github.com/z106…

系统架构设计师【补充知识】: 应用数学 (核心总结)

一、 图论之最小生成树 (1)定义: 在连通的带权图的所有生成树中&#xff0c;权值和最小的那棵生成树(包含图中所有顶点的树)&#xff0c;称作最小生成树。 (2)针对问题: 带权图的最短路径问题。 (3)最小生成树的解法有普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法&#xff0c;我…

liquibase做数据库版本管理

通过这个配置就会自动启动liquibase 比对 https://www.cnblogs.com/ludangxin/p/16676701.html https://zhuyizhuo.github.io/2020/07/04/spring-boot/spring-boot-liquibase-database-version-control/

通过语言大模型来学习tensorflow框架训练模型(三)

一、模型训练5步骤走 1.数据获取&#xff0c;2&#xff0c;数据处理&#xff0c;3.模型创建与训练&#xff0c;4 模型测试与评估&#xff0c;5.模型预测 二、tensorflow数据获取 在TensorFlow中&#xff0c;数据获取和预处理是构建深度学习模型的重要步骤。TensorFlow提供了多…

wireshark抓包ssl数据出现ignored unknown record的原因

文章目录 前言一、出现原因二、wireshark抓包分析Ignored Unknown RecordTCP segment of a reassembled PDU 总结 前言 使用下面这个例子来观察记录层数据大于TCP MSS时用wireshark抓包出现ignored unknown record的情况并分析原因。 c语言利用openssl实现简单客户端和服务端&…

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

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

SpringBoot整合H2数据库并将其打包成jar包、转换成exe文件

SpringBoot整合H2数据库并将其打包成jar包、转换成exe文件 H2 是一个用 Java 开发的嵌入式数据库&#xff0c;它的主要特性使其成为嵌入式应用程序的理想选择。H2 仅是一个类库&#xff0c;可以直接嵌入到应用项目中&#xff0c;而无需独立安装客户端和服务器端。 常用开源数…

【因果推断python】31_合成控制1

目录 一个了解无从知晓事情的超酷数学技巧 我们有时间 一个了解无从知晓事情的超酷数学技巧 当我们审视双重差分法时&#xff0c;我们有来自 2 个不同城市的多个客户的数据&#xff1a;阿雷格里港和弗洛里亚诺波利斯。数据跨越 2 个不同的时间段&#xff1a;在阿雷格里港进行…