以下是几种实现 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:将脚本挂载到任意 GameObject,在 Inspector 中拖拽对应的 Scrollbar 和 Panel
-
方法2:直接使用 Unity 自带的 ScrollRect 组件
-
方法3:需要平滑滚动效果时使用
-
方法4:需要同时控制水平和垂直滚动时使用
注意事项:
-
确保 Panel 的锚点设置正确
-
调整
minPosition和maxPosition来匹配你的实际需求 -
使用
Mathf.Lerp可以确保值在指定范围内平滑过渡
DEEP SEEK生成