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

Unity 2D玩家移动减速功能失效问题求助

问题:2D横版卷轴游戏玩家移动减速逻辑失效

为2D横版卷轴游戏编写了C#玩家移动脚本,尝试基于前序速度和当前移动方向实现加减速效果。目前加速功能正常,但松开输入后玩家速度直接跳至0,完全忽略减速逻辑。使用Unity InputSystem插件,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    private float horizontalController;
    private float horizontal = 1f;
    public float currentSpeed = 0f;
    public float acceleration = 0.03f;
    public float deceleration = 0.1f;
    public float maxSpeed = 50f;
    public float jumpPower = 10f;

    private Rigidbody2D rb;
    [SerializeField] private Transform groundCheck;
    [SerializeField] private LayerMask groundLayer;

    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        rb.velocity = new Vector2 (currentSpeed, rb.velocity.y); 
        CalculateSpeed();
        Debug.Log(currentSpeed);
    }

    private void Update()
    {
       
    }

    private bool IsGrounded()
    {
        return Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
    }

    public void Jump(InputAction.CallbackContext cc)
    {
        if (cc.performed && IsGrounded())
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpPower);
        }

        if (cc.canceled && rb.velocity.y > 0f)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpPower * 0.5f);
        }
    }

    public void Move(InputAction.CallbackContext cc)
    {
        horizontalController = cc.ReadValue<Vector2>().x;
        
    }

    private void CalculateSpeed()
    {
        if(horizontalController > 0.1f)
        {
            currentSpeed += acceleration;
        } else if (horizontalController < 0.1f)
        {
            currentSpeed -= acceleration;
        } else
        {
            if(currentSpeed > 0f)
            {
                currentSpeed -= deceleration;
            } else if(currentSpeed < 0f)
            {
                currentSpeed += deceleration;
            }
        }
        currentSpeed = Mathf.Clamp(currentSpeed, -Mathf.Abs(maxSpeed * horizontalController), Mathf.Abs(maxSpeed * horizontalController));
    }

}
解决方案

问题出在两个关键逻辑上:

  • 方向判断条件错误
    CalculateSpeed里的else if (horizontalController < 0.1f)会把所有小于0.1的输入(包括负数和0)都归为向左加速的分支,导致松开输入(horizontalController=0)时不会进入减速的else分支。需要改成else if (horizontalController < -0.1f),这样只有明确的向左输入才会触发向左加速。

  • 速度Clamp范围错误
    最后一行的Mathf.Clamp使用maxSpeed * horizontalController作为范围,当松开输入时horizontalController=0,范围会变成[0,0],直接把currentSpeed强制设为0,这就是松开后速度跳0的核心原因。应该基于当前速度的方向来确定Clamp范围,或者用输入方向的正负来保留最大速度限制,而不是依赖输入值的大小。

修复后的CalculateSpeed方法:

private void CalculateSpeed()
{
    if(horizontalController > 0.1f)
    {
        currentSpeed += acceleration;
        // 加速时限制最大速度为正的maxSpeed
        currentSpeed = Mathf.Clamp(currentSpeed, 0, maxSpeed);
    } else if (horizontalController < -0.1f)
    {
        currentSpeed -= acceleration;
        // 加速时限制最大速度为负的maxSpeed
        currentSpeed = Mathf.Clamp(currentSpeed, -maxSpeed, 0);
    } else
    {
        if(currentSpeed > 0f)
        {
            currentSpeed -= deceleration;
            // 减速时避免速度变为负数
            if(currentSpeed < 0f) currentSpeed = 0f;
        } else if(currentSpeed < 0f)
        {
            currentSpeed += deceleration;
            // 减速时避免速度变为正数
            if(currentSpeed > 0f) currentSpeed = 0f;
        }
    }
}

额外优化:建议在FixedUpdate里先调用CalculateSpeed再设置rb.velocity,这样逻辑顺序更合理,避免帧延迟。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 11:07:16