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

相关推荐
在路上看风景17 小时前
## 2.2 状态同步
unity
霜绛18 小时前
Unity:lua热更新(一)——AB包AssetBundle、Lua语法
笔记·学习·游戏·unity·lua
霜绛18 小时前
Unity:lua热更新(二)——Lua语法(续)
笔记·学习·unity·游戏引擎·lua
yi碗汤园19 小时前
【一文了解】C#反射
开发语言·unity·c#
HahaGiver66620 小时前
Unity Shader Graph 3D 实例 - 基础的模型贴图渲染
3d·unity·游戏程序·贴图·游戏美术
HahaGiver66620 小时前
Unity Shader Graph 3D 实例 - 一个简单的3D打印效果
3d·unity·游戏引擎
AA陈超20 小时前
ASC学习笔记0004:通知相关方能力规格已被修改
c++·笔记·学习·游戏·ue5·游戏引擎·虚幻
胖胖求游戏1 天前
Unity热更新——AB包和Lua
unity·游戏引擎·lua
为你写首诗ge1 天前
【Unity知识分享】Unity中获取Pico设备的序列号(SN码)
unity