如何在老虎机卷轴中让移动图片到达指定位置时精准停止?
老虎机卷轴精准停止解决方案
核心问题在于直接用==比较浮点数位置,帧依赖的移动很难刚好卡到目标值,且浮点数精度误差会导致判断失效。以下是两种精准停止的实现方案:
方案一:阈值判断+直接到位
定义一个停止阈值,当目标卷轴元素与停止位置的距离小于单帧移动距离时,直接将元素设置到目标位置,彻底避免精度误差:
// 新增停止阈值(建议略大于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
相关产品推荐
相关产品推荐

