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生成

相关推荐
沉默金鱼7 小时前
Unity实用技能-GM命令
unity·游戏引擎
chillxiaohan8 小时前
unity粗糙、高光、光泽度调节shader记录
unity·游戏引擎
星夜泊客10 小时前
Unity UI 渲染与 Rebuild 机制简易解析
unity·游戏引擎
一线灵13 小时前
跨平台游戏引擎 Axmol-2.11.1 发布
游戏引擎
qiminixi21 小时前
Unity 6000下载
unity·unity 6000·unity 6000下载
CreasyChan1 天前
Unity Shader 入门指南
unity·c#·游戏引擎·shader
漂视数字孪生世界1 天前
Unity团结引擎的前世今生
unity·游戏引擎·数字孪生
心前阳光1 天前
Unity通过ScriptableObject学习访问者模式
学习·unity·访问者模式
fcm191 天前
unity之重新导入TMP
unity
心疼你的一切1 天前
【技术创作的璀璨盛宴——2025年CSDN博客之星总评选深度总结】
microsoft·unity·游戏引擎·游戏程序·csdn·博客之星