Unity 实现 ScrollBar 值变化控制 Panel 位置的方法

以下是几种实现 ScrollBar 值变化控制 Panel 位置的方法:

方法1:直接控制位置(推荐)

cs 复制代码
using UnityEngine;
using UnityEngine.UI;

public class ScrollController : MonoBehaviour
{
    [Header("UI References")]
    public Scrollbar scrollbar;
    public RectTransform panel; // 要移动的Panel
    
    [Header("Scroll Settings")]
    public float minYPosition = 0f;   // 最小Y位置
    public float maxYPosition = 100f; // 最大Y位置
    public bool horizontalScroll = false; // 是否水平滚动
    
    private void Start()
    {
        // 添加监听事件
        scrollbar.onValueChanged.AddListener(OnScrollbarValueChanged);
        
        // 初始化位置
        OnScrollbarValueChanged(scrollbar.value);
    }
    
    private void OnScrollbarValueChanged(float value)
    {
        if (panel == null) return;
        
        if (horizontalScroll)
        {
            // 水平滚动:控制X位置
            float newX = Mathf.Lerp(minYPosition, maxYPosition, value);
            panel.anchoredPosition = new Vector2(newX, panel.anchoredPosition.y);
        }
        else
        {
            // 垂直滚动:控制Y位置
            float newY = Mathf.Lerp(minYPosition, maxYPosition, value);
            panel.anchoredPosition = new Vector2(panel.anchoredPosition.x, newY);
        }
    }
    
    private void OnDestroy()
    {
        // 移除监听,防止内存泄漏
        if (scrollbar != null)
            scrollbar.onValueChanged.RemoveListener(OnScrollbarValueChanged);
    }
}

方法2:使用 ScrollRect(更简单)

cs 复制代码
using UnityEngine;
using UnityEngine.UI;

public class SimpleScrollController : MonoBehaviour
{
    public ScrollRect scrollRect;
    
    void Start()
    {
        // 自动获取或手动指定ScrollRect
        if (scrollRect == null)
            scrollRect = GetComponent<ScrollRect>();
    }
    
    // 外部调用更新滚动位置
    public void UpdateScrollPosition(float value)
    {
        if (scrollRect != null)
        {
            scrollRect.verticalNormalizedPosition = 1 - value; // 反转值(Unity的滚动方向)
        }
    }
}

方法3:平滑滚动效果

cs 复制代码
using UnityEngine;
using UnityEngine.UI;

public class SmoothScrollController : MonoBehaviour
{
    public Scrollbar scrollbar;
    public RectTransform panel;
    
    [Header("Smooth Settings")]
    public float smoothTime = 0.1f;
    public float maxYPosition = 100f;
    
    private float targetPosition;
    private float currentVelocity;
    
    private void Start()
    {
        scrollbar.onValueChanged.AddListener(OnScrollValueChanged);
    }
    
    private void OnScrollValueChanged(float value)
    {
        targetPosition = Mathf.Lerp(0, maxYPosition, value);
    }
    
    private void Update()
    {
        // 平滑过渡到目标位置
        float currentY = panel.anchoredPosition.y;
        float newY = Mathf.SmoothDamp(currentY, targetPosition, ref currentVelocity, smoothTime);
        
        panel.anchoredPosition = new Vector2(panel.anchoredPosition.x, newY);
    }
    
    private void OnDestroy()
    {
        if (scrollbar != null)
            scrollbar.onValueChanged.RemoveListener(OnScrollValueChanged);
    }
}

方法4:完整的双向滚动控制

cs 复制代码
using UnityEngine;
using UnityEngine.UI;

public class AdvancedScrollController : MonoBehaviour
{
    public Scrollbar horizontalScrollbar;
    public Scrollbar verticalScrollbar;
    public RectTransform contentPanel;
    
    [Header("Scroll Limits")]
    public Vector2 minPosition = Vector2.zero;
    public Vector2 maxPosition = new Vector2(100f, 100f);
    
    private void Start()
    {
        if (horizontalScrollbar != null)
            horizontalScrollbar.onValueChanged.AddListener(OnHorizontalScroll);
            
        if (verticalScrollbar != null)
            verticalScrollbar.onValueChanged.AddListener(OnVerticalScroll);
    }
    
    private void OnHorizontalScroll(float value)
    {
        float newX = Mathf.Lerp(minPosition.x, maxPosition.x, value);
        contentPanel.anchoredPosition = new Vector2(
            newX, 
            contentPanel.anchoredPosition.y
        );
    }
    
    private void OnVerticalScroll(float value)
    {
        float newY = Mathf.Lerp(minPosition.y, maxPosition.y, value);
        contentPanel.anchoredPosition = new Vector2(
            contentPanel.anchoredPosition.x, 
            newY
        );
    }
    
    // 更新滚动条值(当通过其他方式移动Panel时调用)
    public void UpdateScrollbarValues()
    {
        if (horizontalScrollbar != null)
        {
            float horizontalValue = Mathf.InverseLerp(
                minPosition.x, 
                maxPosition.x, 
                contentPanel.anchoredPosition.x
            );
            horizontalScrollbar.value = horizontalValue;
        }
        
        if (verticalScrollbar != null)
        {
            float verticalValue = Mathf.InverseLerp(
                minPosition.y, 
                maxPosition.y, 
                contentPanel.anchoredPosition.y
            );
            verticalScrollbar.value = verticalValue;
        }
    }
    
    private void OnDestroy()
    {
        if (horizontalScrollbar != null)
            horizontalScrollbar.onValueChanged.RemoveListener(OnHorizontalScroll);
        if (verticalScrollbar != null)
            verticalScrollbar.onValueChanged.RemoveListener(OnVerticalScroll);
    }
}

使用方法:

  1. 方法1:将脚本挂载到任意 GameObject,在 Inspector 中拖拽对应的 Scrollbar 和 Panel

  2. 方法2:直接使用 Unity 自带的 ScrollRect 组件

  3. 方法3:需要平滑滚动效果时使用

  4. 方法4:需要同时控制水平和垂直滚动时使用

注意事项:

  • 确保 Panel 的锚点设置正确

  • 调整 minPositionmaxPosition 来匹配你的实际需求

  • 使用 Mathf.Lerp 可以确保值在指定范围内平滑过渡

DEEP SEEK生成

相关推荐
mxwin7 小时前
Unity Shader 顶点动画:在顶点着色器中实现风吹草动、河流波动、布料模拟
unity·游戏引擎·shader·着色器
DowneyJoy7 小时前
【Unity3D补充知识点】常用数据结构分析-集合(List<T>)
数据结构·unity·c#·list
DowneyJoy8 小时前
【Unity3D补充知识点】常用数据结构分析-数组(Array)
数据结构·unity·c#
w-白兰地9 小时前
配置Unity中的ADB环境变量
unity·adb·游戏引擎
mxwin9 小时前
Unity Shader 几何着色器:动态生成图元与顶点拓扑修改
unity·游戏引擎·着色器
呆呆敲代码的小Y10 小时前
【Unity-AI开发篇】| 游戏中接入DeepSeek实现AI对话,完整详细步骤
人工智能·游戏·unity·ai·游戏引擎·u3d·deepseek
相信神话20211 天前
第四章:Godot 4.6 核心概念与开发环境搭建
游戏引擎·godot·2d游戏编程·godot4·2d游戏开发
代数狂人1 天前
在Godot中应用面向对象原则:C#脚本实践
c#·游戏引擎·godot
Sator11 天前
Unity关于射击游戏人物动画的设计经验
游戏·unity·游戏引擎
冰凌糕1 天前
Unity3D Shader 坐标空间详解
unity