You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity带加减按钮的动态UI数字选择器长按加速功能开发求助

嘿,我刚好在Unity里做过一模一样的功能,给你一套完全贴合需求的C#实现方案,直接就能用:

核心实现思路
  1. 用Unity的指针事件接口(IPointerDownHandler/IPointerUpHandler)精准检测按钮的按住、松开状态,比普通的Button.onClick更适合处理长按逻辑
  2. 设置0.2秒的长按阈值,按住时间没到就只执行单次增减,超过阈值后启动连续增减的协程
  3. 加速度逻辑:通过线性插值计算增减间隔,从初始的每秒3次(间隔≈0.333秒),在2秒内平滑过渡到每秒20次(间隔≈0.05秒),按住时间越久速度越快
完整代码

把下面的脚本挂在你的加号、减号按钮上,注意给两个按钮分别设置direction参数(加号传1,减号传-1):

using UnityEngine;
using UnityEngine.EventSystems;
using TMPro;

public class NumberAdjustButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
    [Header("UI引用")]
    public TextMeshProUGUI numberDisplay; // 中间显示数字的TextMeshPro

    [Header("数值范围")]
    public int minValue = 0;
    public int maxValue = 100;
    private int currentValue;

    [Header("长按设置")]
    public int direction = 1; // 1=加,-1=减
    private const float holdThreshold = 0.2f; // 长按触发的时间阈值
    private float initialInterval = 1f / 3f; // 初始每秒3次,间隔1/3秒
    private float maxInterval = 1f / 20f; // 最大每秒20次,间隔1/20秒
    private float accelerationDuration = 2f; // 从初始到最大速度的过渡时间(秒)

    private bool isHolding = false;
    private Coroutine continuousChangeCoroutine;

    private void Start()
    {
        // 初始化当前数值
        currentValue = minValue;
        UpdateDisplay();
    }

    // 处理按钮按下事件
    public void OnPointerDown(PointerEventData eventData)
    {
        isHolding = true;
        // 启动连续增减的协程
        continuousChangeCoroutine = StartCoroutine(ChangeValueContinuously());
    }

    // 处理按钮松开事件
    public void OnPointerUp(PointerEventData eventData)
    {
        StopContinuousChange();
    }

    // 处理鼠标移出按钮事件(防止移出后还在触发)
    public void OnPointerExit(PointerEventData eventData)
    {
        StopContinuousChange();
    }

    // 停止连续增减的协程
    private void StopContinuousChange()
    {
        isHolding = false;
        if (continuousChangeCoroutine != null)
        {
            StopCoroutine(continuousChangeCoroutine);
            continuousChangeCoroutine = null;
        }
    }

    // 连续增减数值的协程
    private IEnumerator ChangeValueContinuously()
    {
        // 先等待长按阈值时间,如果这段时间内松开了,就只执行一次增减
        yield return new WaitForSeconds(holdThreshold);

        // 如果已经松开,直接返回
        if (!isHolding) yield break;

        // 首次执行一次增减(补上长按阈值期间的操作)
        AdjustValue();

        float holdElapsedTime = 0f;
        while (isHolding)
        {
            // 计算当前的间隔:根据按住的时间,从初始间隔向最大间隔插值
            float currentInterval = Mathf.Lerp(initialInterval, maxInterval, holdElapsedTime / accelerationDuration);
            yield return new WaitForSeconds(currentInterval);

            if (isHolding)
            {
                AdjustValue();
                holdElapsedTime += currentInterval;
                // 防止时间超过加速时长后继续变化,固定到最大值
                holdElapsedTime = Mathf.Min(holdElapsedTime, accelerationDuration);
            }
        }
    }

    // 单次增减数值的方法
    private void AdjustValue()
    {
        currentValue += direction;
        // 限制数值在min和max之间
        currentValue = Mathf.Clamp(currentValue, minValue, maxValue);
        UpdateDisplay();
    }

    // 更新数字显示
    private void UpdateDisplay()
    {
        numberDisplay.text = currentValue.ToString();
    }
}
使用说明
  1. 在Unity场景中创建三个按钮:减号按钮、数字显示区域(用TextMeshPro做显示,不需要点击事件)、加号按钮
  2. 给加号、减号按钮分别挂载上面的脚本
  3. 把数字显示的TextMeshPro拖到两个脚本的numberDisplay字段中
  4. 设置加号按钮的direction为1,减号按钮的direction为-1
  5. 根据你的需求调整minValue、maxValue、accelerationDuration等参数
  6. 运行测试:点击按钮单次增减,长按超过0.2秒后会开始连续增减,并且速度会越来越快直到最大值

这个方案完美覆盖了你所有的需求:单次点击增减、长按连续增减、加速度阶段,而且代码结构清晰,注释也很详细,你可以根据自己的需求调整参数~

内容的提问来源于stack exchange,提问作者pro1p

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:52:35