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

如何在老虎机卷轴中让移动图片到达指定位置时精准停止?

老虎机卷轴精准停止解决方案

核心问题在于直接用==比较浮点数位置,帧依赖的移动很难刚好卡到目标值,且浮点数精度误差会导致判断失效。以下是两种精准停止的实现方案:

方案一:阈值判断+直接到位

定义一个停止阈值,当目标卷轴元素与停止位置的距离小于单帧移动距离时,直接将元素设置到目标位置,彻底避免精度误差:

// 新增停止阈值(建议略大于scrollSpeed,可根据实际效果调整)
public float stopThreshold = 1.5f;

private void Update()
{
    if (canSpin)
        SpinReall();

    if (Input.GetKeyDown(KeyCode.Space))
    {
        if (!canSpin)
        {
            canSpin = true;
            canStop = false;
        }
        else
        {
            canStop = true;
        }
    }
}

public void SpinReall()
{
    foreach (RectTransform slot in slots)
    {
        // 正常循环滚动逻辑
        Vector3 newPos = new Vector3(0, slot.localPosition.y - scrollSpeed);
        slot.localPosition = newPos;
        if (slot.localPosition.y <= bottomBorder)
        {
            Vector3 currentPosition = slot.localPosition;
            currentPosition.y += offsetPosition;
            slot.localPosition = currentPosition;
        }

        // 精准停止逻辑
        if (canStop)
        {
            RectTransform targetSlot = slots[stopIndex];
            float targetY = stopPoss.localPosition.y;
            float currentY = targetSlot.localPosition.y;
            float distance = Mathf.Abs(currentY - targetY);

            // 处理循环卷轴的跨边界情况(目标位置在当前元素上方)
            if (currentY < targetY)
            {
                distance = Mathf.Abs(currentY + offsetPosition - targetY);
            }

            // 当距离足够近时,直接定位到目标位置并停止滚动
            if (distance <= stopThreshold)
            {
                targetSlot.localPosition = new Vector3(targetSlot.localPosition.x, targetY, targetSlot.localPosition.z);
                canSpin = false;
                canStop = false;
                break;
            }
        }
    }
}

方案二:减速平滑停止

如果需要更自然的停止动画,可加入减速逻辑,逐帧降低滚动速度直到精准到位:

// 新增减速系数(值越大减速越快)
public float deceleration = 2f;
private float currentScrollSpeed;

private void Start()
{
    currentScrollSpeed = scrollSpeed;
}

private void Update()
{
    if (canSpin)
        SpinReall();

    if (Input.GetKeyDown(KeyCode.Space))
    {
        if (!canSpin)
        {
            canSpin = true;
            currentScrollSpeed = scrollSpeed;
            canStop = false;
        }
        else
        {
            canStop = true;
        }
    }
}

public void SpinReall()
{
    foreach (RectTransform slot in slots)
    {
        // 滚动/减速滚动逻辑
        Vector3 newPos = new Vector3(0, slot.localPosition.y - currentScrollSpeed);
        slot.localPosition = newPos;
        if (slot.localPosition.y <= bottomBorder)
        {
            Vector3 currentPosition = slot.localPosition;
            currentPosition.y += offsetPosition;
            slot.localPosition = currentPosition;
        }

        // 精准停止逻辑
        if (canStop)
        {
            RectTransform targetSlot = slots[stopIndex];
            float targetY = stopPoss.localPosition.y;
            float currentY = targetSlot.localPosition.y;
            float distance = Mathf.Abs(currentY - targetY);

            // 处理跨边界情况
            if (currentY < targetY)
            {
                distance = Mathf.Abs(currentY + offsetPosition - targetY);
            }

            // 未到停止阈值时持续减速,到达后直接定位
            if (distance > stopThreshold)
            {
                currentScrollSpeed = Mathf.Lerp(currentScrollSpeed, 0, deceleration * Time.deltaTime);
            }
            else
            {
                targetSlot.localPosition = new Vector3(targetSlot.localPosition.x, targetY, targetSlot.localPosition.z);
                canSpin = false;
                canStop = false;
                currentScrollSpeed = scrollSpeed;
                break;
            }
        }
    }
}

关键优化点

  • 替换==浮点数比较为距离阈值判断,彻底规避精度误差
  • 处理循环卷轴的跨边界情况,确保目标位置在上方时也能精准停止
  • 方案二新增减速逻辑,让停止动画更自然,同时保证最终位置绝对精准

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:45:21