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

Unity中奔跑状态仅瞬现:无法稳定切换至running状态的问题求助

解决Unity 2D平台游戏奔跑仅触发一瞬间的问题

嘿,我一眼就看出问题所在啦——你误用了Unity的输入检测API,导致奔跑状态只能在按键按下的第一帧生效,没法持续触发。咱们一步步来修复:

问题根源

GetKeyDown 和 GetButtonDown 这两个方法只在按键被按下的那单一帧返回true,而奔跑是需要按住Shift+方向键持续生效的操作,所以得换成检测「按键是否处于按住状态」的API:GetKey 和 GetButton。

具体修改点

1. 移动逻辑的奔跑判断

你原来的奔跑代码只在同时按下方向键和Shift的瞬间执行一次,之后每一帧都会被上面的走路速度覆盖。应该调整逻辑,先判断是否处于奔跑状态,再统一设置速度:

把原来的:

// WALKING MOVEMENT
rb.velocity = new Vector2(dirX * walkSpeed, rb.velocity.y);

// RUNNING MOVEMENT
if (Input.GetButtonDown("Horizontal") && Input.GetKeyDown(KeyCode.LeftShift))
{
    rb.velocity = new Vector2(dirX * runSpeed, rb.velocity.y);
}

改成:

// 先判断是否处于奔跑状态
float currentSpeed = walkSpeed;
if (Input.GetButton("Horizontal") && Input.GetKey(KeyCode.LeftShift))
{
    currentSpeed = runSpeed;
}
// 统一设置速度
rb.velocity = new Vector2(dirX * currentSpeed, rb.velocity.y);

2. 动画状态的奔跑判断

动画部分同样用了GetKeyDown,导致只有按下Shift的那帧会切换到奔跑动画,之后立刻变回走路。把两处Input.GetKeyDown(KeyCode.LeftShift)换成Input.GetKey(KeyCode.LeftShift):

修改后的UpdateAnimationState里的判断:

if (dirX > 0f)
{
    if (Input.GetKey(KeyCode.LeftShift)) // 这里改成GetKey
    {
        state = MovementState.running;
    }
    else
    {
        state = MovementState.walking;
    }
    sprite.flipX = false;
}
else if (dirX < 0f)
{
    if (Input.GetKey(KeyCode.LeftShift)) // 这里也改成GetKey
    {
        state = MovementState.running;
    }
    else
    {
        state = MovementState.walking;
    }
    sprite.flipX = true;
}

修改后的完整代码

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

public class PlayerMovement : MonoBehaviour
{
    private Rigidbody2D rb;
    private SpriteRenderer sprite;
    private Animator anim;

    private float dirX = 0f;
    [SerializeField] private float walkSpeed = 3f;
    [SerializeField] private float runSpeed = 7f;
    [SerializeField] private float jumpForce = 14f;

    private enum MovementState { idle, walking, running, jumping, falling }

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        sprite = GetComponent<SpriteRenderer>();
        anim = GetComponent<Animator>();
    }

    void Update()
    {
        dirX = Input.GetAxisRaw("Horizontal");

        // 移动逻辑:先判断奔跑状态,再设置速度
        float currentSpeed = walkSpeed;
        if (Input.GetButton("Horizontal") && Input.GetKey(KeyCode.LeftShift))
        {
            currentSpeed = runSpeed;
        }
        rb.velocity = new Vector2(dirX * currentSpeed, rb.velocity.y);

        // 跳跃逻辑保持不变
        if (Input.GetButtonDown("Jump"))
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
        }

        UpdateAnimationState();
    }
    
    private void UpdateAnimationState()
    {
        MovementState state;

        // 奔跑、走路、 idle 动画判断
        if (dirX > 0f)
        {
            if (Input.GetKey(KeyCode.LeftShift))
            {
                state = MovementState.running;
            }
            else
            {
                state = MovementState.walking;
            }
            sprite.flipX = false;
        }
        else if (dirX < 0f)
        {
            if (Input.GetKey(KeyCode.LeftShift))
            {
                state = MovementState.running;
            }
            else
            {
                state = MovementState.walking;
            }
            sprite.flipX = true;
        }
        else
        {
            state = MovementState.idle;
        }

        // 跳跃、下落动画保持不变
        if (rb.velocity.y > .1f)
        {
            state = MovementState.jumping;
        }
        else if (rb.velocity.y < -.1f)
        {
            state = MovementState.falling;
        }

        anim.SetInteger("state", (int)state);
    }
}

额外小建议

如果你想让控制更灵活(比如允许玩家在Unity输入设置里自定义奔跑键),可以在「Edit > Project Settings > Input Manager」里添加一个名为Run的输入轴,然后把代码里的Input.GetKey(KeyCode.LeftShift)换成Input.GetButton("Run"),这样以后改按键不用改代码啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 17:20:19