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

Unity中如何实现转盘旋转后平滑停止并保证仅顺时针旋转

修正后完整代码

public class WheelOptions : MonoBehaviour
{
    [SerializeField] int spinDuration = 5;
    [SerializeField] float decelerationDuration = 2f; // 减速阶段时长,可自行调整
    [SerializeField] int seedValue = 5;
    [SerializeField] SectionColors[] sectionColors;

    Vector3 targetPosition;

    bool isSpinning = false;
    bool isDecelerating = false; // 新增减速状态标记
    int currentSpin = 0;
    float targetSpinAngle; // 存储目标旋转角度(Y轴欧拉角)

    void Start()
    {
        targetPosition = new Vector3(Random.Range(-5, 5), 0f, Random.Range(-5, 5));
    }

    public void SpinWheel()
    {
        if (isSpinning || isDecelerating) return; // 防止重复触发

        isSpinning = true;
        targetPosition = new Vector3(Random.Range(-5, 5), 0f, Random.Range(-5, 5));
        StartCoroutine(SpinProcess());
    }

    void Update()
    {
        transform.position = Vector3.zero;
    
        if (isSpinning)
        {
            // 基础匀速旋转逻辑,保持顺时针
            currentSpin = (currentSpin + 1) % 360;
            transform.rotation = Quaternion.Euler(0, currentSpin, 0);
        }
    }

    IEnumerator SpinProcess()
    {
        // 先匀速旋转设定的时长
        yield return new WaitForSeconds(spinDuration);

        // 进入减速阶段
        isSpinning = false;
        isDecelerating = true;

        // 计算目标Y轴旋转角度
        Quaternion targetRot = Quaternion.LookRotation(targetPosition - transform.position, Vector3.up);
        float rawTargetAngle = targetRot.eulerAngles.y;

        // 校准目标角度,保证大于当前角度,强制顺时针旋转,额外加2圈让减速过程更自然
        targetSpinAngle = rawTargetAngle < currentSpin ? rawTargetAngle + 360 : rawTargetAngle;
        targetSpinAngle += 720;

        float timeElapsed = 0f;
        Quaternion startRot = transform.rotation;
        Quaternion finalRot = Quaternion.Euler(0, targetSpinAngle, 0);

        while (timeElapsed < decelerationDuration)
        {
            timeElapsed += Time.deltaTime;
            // 用SmoothStep做缓动,实现先快后慢的减速效果
            float t = Mathf.SmoothStep(0, 1, timeElapsed / decelerationDuration);
            // Slerp插值旋转
            transform.rotation = Quaternion.Slerp(startRot, finalRot, t);
            yield return null;
        }

        // 校准最终角度,避免浮点误差
        transform.rotation = Quaternion.Euler(0, rawTargetAngle, 0);
        isDecelerating = false;
    }
}

核心修改说明

  • 新增减速状态与减速时长参数,将原来的两段式状态逻辑调整为「匀速旋转→减速停止」的连贯流程,避免状态切换时的突兀跳转
  • 计算目标角度时做了偏移校准,确保目标旋转角度始终大于当前旋转角度,强制全程仅沿顺时针旋转,不会出现Slerp走最短路径倒转的问题
  • 减速阶段使用Mathf.SmoothStep配合Quaternion.Slerp实现自然的减速曲线,越接近停止位置旋转速度越慢,符合真实物理转盘的停止效果
  • 增加重复触发保护,避免旋转过程中再次点击SpinWheel导致逻辑混乱

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:09:02