16.ScrollView滚动视图

  1. 16.UGUI基础-组合控件-ScrollView滚动视图控件
    1. 16.1 知识点
      1. ScrollRect是什么
      2. ScrollRect滚动视图组件参数
        1. Content 内容
        2. Horizontal 水平
        3. Vertical 垂直
        4. Movement Type 运动类型
        5. Inertia 惯性
        6. Deceleration Rate 减速率
        7. Scroll Sensitivity 滚轮灵敏度
        8. Viewport 视口
        9. Horizontal Scrollbar 水平滚动条
        10. Visibility 可视性
        11. Spacing 间距
        12. OnValueChanged 值改变时
      3. ScrollRect滚动视图代码控制
        1. this.GetComponent<ScrollRect>() 获取ScrollRect组件
        2. ScrollRect.content.sizeDelta 改变内容对象的大小
        3. ScrollRect.normalizedPosition 设置滑动面板的归一化位置
      4. ScrollView监听事件的两种方式
        1. 拖脚本监听事件
        2. 代码添加监听事件
    2. 16.2 知识点代码
    3. 16.3 练习题
      1. 在上节课的练习题基础上,请用现在所学知识,制作一个这样的功能:有一个背包按钮,点击后可以打开一个背包面板,面板中有一个滚动视图,滚动视图中动态创建10个道具图标
        1. 在游戏面板中创建一个背包按钮控件,用于点击打开背包面板
        2. 创建一个背包面板。包含一个滚动视图控件和关闭背包面板按钮。滚动视图只保留竖直拖动条,并且设置只能竖直拖动。创建一个图片,锚点改成左上,模拟道具情况。之后代码动态创建道具时,要算出道具图片的位置。同时要把content的大小改大。
        3. 把道具图片做成预制体,等一下动态加载
        4. 创建BagPanel脚本,挂载到背包面板。做成单例模式。创建关闭按钮变量和道具滚动视图变量,外面关联关闭按钮和道具滚动视图。
        5. 在BagPanel脚本中,动态创建道具,用Resource.Load实例化 Item 预制体,作为物品图标,设置父对象为滚动视图的content,重新计算本地坐标系,根据索引设置道具的位置。根据道具数量计算 Content 的高度。注册关闭按钮点击事件,当关闭按钮被点击时,隐藏背包面板。一开始也隐藏背包面板。
        6. 在GamePanel脚本创建背包按钮控件变量,外部关联背包按钮。添加打开背包脚本的监听。
    4. 16.4 练习题代码
      1. BagPanel
      2. GamePanel

16.UGUI基础-组合控件-ScrollView滚动视图控件


16.1 知识点

ScrollRect是什么

ScrollRect是滚动视图组件,是UGUI中用于处理滚动视图相关交互的关键组件。

默认创建的ScrollRect由4组对象组成:

  • 父对象——ScrollRect组件依附的对象,还有一个Image组件,作为背景图。
  • 子对象:
    • Viewport:控制滚动视图可视范围和内容显示。
    • Scrollbar Horizontal:水平滚动条。
    • Scrollbar Vertical:垂直滚动条。


可以直接删除两个滚动条,删除后要在ScrollRect将滚动条关联置空,不然可能会出现bug。删除后最好将视图和图片设置成铺满,以防止保留之前和滚动条之间的缝隙。

ScrollRect滚动视图组件参数


Content 内容

控制滚动视图显示内容的父对象,其尺寸决定了滚动视图的拖动范围,默认关联Viewport的子对象Content。

Horizontal 水平

启用水平滚动。

Vertical 垂直

启用垂直滚动。

Movement Type 运动类型



滚动视图元素的运动类型,主要控制拖动时的反馈效果。

  • Unrestricted:不受限制,随意拖动。
  • Elastic:回弹效果,滚出边缘后会弹回边界。
    • Elasticity:回弹系数,控制回弹效果,值越大回弹越慢。
  • Clamped:夹紧效果,始终限制在范围内,没有回弹效果。

Inertia 惯性

移动惯性,如果开启,松开鼠标后会有一定的移动惯性。

Deceleration Rate 减速率

减速率(0~1),0表示没有惯性,1表示不会停止。

Scroll Sensitivity 滚轮灵敏度

滚轮和触摸板的滚动事件敏感性,增大值可以加快滚轮滚动速度。

Viewport 视口

关联滚动视图内容视口对象,视口对象决定可视范围。

Horizontal Scrollbar 水平滚动条

关联水平滚动条。

Visibility 可视性



设置滚动条的可视性模式。

  • Permanent:一直显示滚动条。
  • Auto Hide:自动隐藏滚动条,不会自动扩展视口范围。就是如果content比Viewport还小,自动隐藏滚动条。
  • Auto Hide And Expand Viewport:自动隐藏滚动条,并自动扩展内容Viewport视口范围。就是如果content比Viewport还小,自动隐藏滚动条,content自动扩展的和Viewport一样大。

Spacing 间距

滚动条和视口之间的间隔空间,控制滚动条和视口之间的间隙大小。

OnValueChanged 值改变时

滚动视图位置改变时执行的函数列表。

ScrollRect滚动视图代码控制

this.GetComponent<ScrollRect>() 获取ScrollRect组件

// 获取当前游戏对象上的 ScrollRect 组件,并将其赋值给 scrollRect 变量
ScrollRect scrollRect = this.GetComponent<ScrollRect>();

ScrollRect.content.sizeDelta 改变内容对象的大小

// 改变内容的大小,具体可以拖动多少都是根据它的尺寸来的
// 这里将内容的大小设置为 (1000, 1000)
scrollRect.content.sizeDelta = new Vector2(1000, 1000);

ScrollRect.normalizedPosition 设置滑动面板的归一化位置

// 假如拖动了content,可以将content位置重置到左上
scrollRect.normalizedPosition = new Vector2(0, 1f);

// 设置滑动面板的归一化位置为 (0, 0.5f)
// 其中 x 表示水平方向的归一化值,范围是 0 到 1,0 表示左边缘,1 表示右边缘
// y 表示垂直方向的归一化值,范围是 0 到 1,0 表示下边缘,1 表示上边缘
//scrollRect.normalizedPosition = new Vector2(0, 0.5f);

ScrollView监听事件的两种方式

拖脚本监听事件

public void ChangeValue(Vector2 v)
{
    print(v);
}

代码添加监听事件

// 注册监听滑动矩形值变化的事件,当滑动矩形的值发生变化时,执行下面的函数
scrollRect.onValueChanged.AddListener((vec) =>
{
    // 打印输出滑动矩形的值
    print(vec);
});

16.2 知识点代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Lesson16_UGUI基础_组合控件_ScrollView滚动视图控件 : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 ScrollRect是什么
        //ScrollRect是滚动视图组件
        //是UGUI中用于处理滚动视图相关交互的关键组件

        //默认创建的ScrollRect由4组对象组成
        //父对象——ScrollRect组件依附的对象 还有一个Image组件 最为背景图
        //子对象
        //Viewport控制滚动视图可视范围和内容显示
        //Scrollbar Horizontal 水平滚动条
        //Scrollbar Vertical 垂直滚动条
        //水平滚动条和垂直滚动条可以删掉 Viewport必须保留

        #endregion

        #region 知识点二 ScrollRect参数相关

        #endregion

        #region 知识点三 ScrollRect代码控制

        // 获取当前游戏对象上的 ScrollRect 组件,并将其赋值给 scrollRect 变量
        ScrollRect scrollRect = this.GetComponent<ScrollRect>();

        // 改变内容的大小,具体可以拖动多少都是根据它的尺寸来的
        // 这里将内容的大小设置为 (200, 200)
        scrollRect.content.sizeDelta = new Vector2(1000, 1000);


        //假如拖动了content 可以把content位置重置到左上 
        scrollRect.normalizedPosition = new Vector2(0, 1f);

        // 设置滑动面板的归一化位置为 (0, 0.5f)
        // 其中 x 表示水平方向的归一化值,范围是 0 到 1,0 表示左边缘,1 表示右边缘
        // y 表示垂直方向的归一化值,范围是 0 到 1,0 表示下边缘,1 表示上边缘
        //scrollRect.normalizedPosition = new Vector2(0, 0.5f);

        #endregion

        #region 知识点四 ScrollView监听事件的两种方式
        //1.拖脚本
        //2.代码添加

        // 注册监听滑动矩形值变化的事件,当滑动矩形的值发生变化时,执行下面的函数
        scrollRect.onValueChanged.AddListener((vec) =>
        {
            // 打印输出滑动矩形的值
            print(vec);
        });

        #endregion
    }

    public void ChangeValue(Vector2 v)
    {
        print(v);
    }
}

16.3 练习题

在上节课的练习题基础上,请用现在所学知识,制作一个这样的功能:有一个背包按钮,点击后可以打开一个背包面板,面板中有一个滚动视图,滚动视图中动态创建10个道具图标

在游戏面板中创建一个背包按钮控件,用于点击打开背包面板

创建一个背包面板。包含一个滚动视图控件和关闭背包面板按钮。滚动视图只保留竖直拖动条,并且设置只能竖直拖动。创建一个图片,锚点改成左上,模拟道具情况。之后代码动态创建道具时,要算出道具图片的位置。同时要把content的大小改大。



把道具图片做成预制体,等一下动态加载

创建BagPanel脚本,挂载到背包面板。做成单例模式。创建关闭按钮变量和道具滚动视图变量,外面关联关闭按钮和道具滚动视图。

public class BagPanel : MonoBehaviour
{
    // 面板的静态实例,可以通过 BagPanel.panel 访问
    public static BagPanel panel;
    
    // 关闭按钮
    public Button btnClose;
    
    // 物品滚动视图
    public ScrollRect svItems;
    
    private void Awake()
    {
        // 将当前面板实例赋值给静态实例变量 panel
        panel = this;
    }
}

在BagPanel脚本中,动态创建道具,用Resource.Load实例化 Item 预制体,作为物品图标,设置父对象为滚动视图的content,重新计算本地坐标系,根据索引设置道具的位置。根据道具数量计算 Content 的高度。注册关闭按钮点击事件,当关闭按钮被点击时,隐藏背包面板。一开始也隐藏背包面板。

void Start()
{
    // 第一步:动态创建格子,设置格子的位置
    // 动态创建 n 个图标作为滚动视图中显示的内容
    for (int i = 0; i < 30; i++)
    {
        // 实例化 Item 预制体,作为物品图标
        GameObject item = Instantiate(Resources.Load<GameObject>("Item"));
        // 将实例化的物品图标设为滚动视图的内容的子对象,并保持位置不变
        item.transform.SetParent(svItems.content, false);
        // 设置格子的位置
        item.transform.localPosition = new Vector3(10, -10, 0) + new Vector3(i % 4 * 160, -i / 4 * 160, 0);
    }
    
    // 第二步:设置 Content 的高度
    // 根据格子数量计算 Content 的高度
    svItems.content.sizeDelta = new Vector2(0, Mathf.CeilToInt(30 / 4f) * 160);
    
    // 注册关闭按钮点击事件,当关闭按钮被点击时,执行下面的函数
    btnClose.onClick.AddListener(() => {
        // 隐藏背包面板
        gameObject.SetActive(false);
    });
    
    // 一开始隐藏自己
    this.gameObject.SetActive(false);
}

在GamePanel脚本创建背包按钮控件变量,外部关联背包按钮。添加打开背包脚本的监听。

// 背包按钮
public Button btnBag;

// 在 Start 方法中调用的方法
void Start()
{
    // 注册背包按钮点击事件,当背包按钮被点击时,执行下面的函数
    btnBag.onClick.AddListener(() => {
        // 打开背包面板
        BagPanel.panel.gameObject.SetActive(true);
    });
}

16.4 练习题代码

BagPanel

// 引用命名空间
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class BagPanel : MonoBehaviour
{
    // 面板的静态实例,可以通过 BagPanel.panel 访问
    public static BagPanel panel;

    // 关闭按钮
    public Button btnClose;

    // 物品滚动视图
    public ScrollRect svItems;

    private void Awake()
    {
        // 将当前面板实例赋值给静态实例变量 panel
        panel = this;
    }

    void Start()
    {
        // 第一步:动态创建格子,设置格子的位置
        // 动态创建 n 个图标作为滚动视图中显示的内容
        for (int i = 0; i < 30; i++)
        {
            // 实例化 Item 预制体,作为物品图标
            GameObject item = Instantiate(Resources.Load<GameObject>("Item"));
            // 将实例化的物品图标设为滚动视图的内容的子对象,并保持位置不变
            item.transform.SetParent(svItems.content, false);
            // 设置格子的位置
            item.transform.localPosition = new Vector3(10, -10, 0) + new Vector3(i % 4 * 160, -i / 4 * 160, 0);
        }

        // 第二步:设置 Content 的高度
        // 根据格子数量计算 Content 的高度
        svItems.content.sizeDelta = new Vector2(0, Mathf.CeilToInt(30 / 4f) * 160);

        // 注册关闭按钮点击事件,当关闭按钮被点击时,执行下面的函数
        btnClose.onClick.AddListener(() => {
            // 隐藏背包面板
            gameObject.SetActive(false);
        });

        // 一开始隐藏自己
        this.gameObject.SetActive(false);
    }
}

GamePanel

// 引用命名空间
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GamePanel : MonoBehaviour
{
    // 面板的静态实例,可以通过 GamePanel.panel 访问
    public static GamePanel panel;

    // 攻击按钮
    public Button btnAtk;

    // 音效开关
    public Toggle togOn;
    public Toggle togOff;
    public ToggleGroup tg;

    // 音效大小滑动条
    public Slider sliderSound;

    // 玩家名称文本框
    public Text txtName;
    public Button btnChangeName;

    // 玩家对象
    public PlayerObject player;

    // 背包按钮
    public Button btnBag;

    private void Awake()
    {
        // 将当前面板实例赋值给静态实例变量 panel
        panel = this;
    }

    // 在 Start 方法中调用的方法
    void Start()
    {
        // 注册攻击按钮点击事件,当攻击按钮被点击时,执行下面的函数
        btnAtk.onClick.AddListener(() =>
        {
            // 得到玩家对象,进行开火操作
            player.Fire();
        });

        // 注册改名按钮点击事件,当改名按钮被点击时,执行下面的函数
        btnChangeName.onClick.AddListener(() => {
            // 显示改名面板
            ChangeNamePanel.panel.gameObject.SetActive(true);
        });

        // 注册音效开关的值改变事件,当音效开关的值发生改变时,执行下面的函数
        togOn.onValueChanged.AddListener(TogChangeValue);
        togOff.onValueChanged.AddListener(TogChangeValue);

        // 初始化音效大小滑动条的值,通过数据初始化
        sliderSound.value = MusicData.SoundValue;

        // 监听音效大小滑动条的值改变事件
        sliderSound.onValueChanged.AddListener((v) =>
        {
            // 处理音效的大小,将滑动条的值赋值给 MusicData.SoundValue
            MusicData.SoundValue = v;
        });

        // 注册背包按钮点击事件,当背包按钮被点击时,执行下面的函数
        btnBag.onClick.AddListener(() => {
            // 打开背包面板
            BagPanel.panel.gameObject.SetActive(true);
        });
    }

    private void TogChangeValue(bool v)
    {
        // 得到当前激活的 Toggle
        foreach (Toggle item in tg.ActiveToggles())
        {
            if (item == togOn)
            {
                // 当选择的是开启音效时,将 MusicData.SoundIsOpen 设置为 true
                MusicData.SoundIsOpen = true;
            }
            else if (item == togOff)
            {
                // 当选择的是关闭音效时,将 MusicData.SoundIsOpen 设置为 false
                MusicData.SoundIsOpen = false;
            }
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏