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

Unity:如何实现按住键盘让GameObject单次移动1单位且避免重复移动?

解决Unity方向键按住时角色重复移动的问题

我正在制作一款解谜平台游戏,主角通过方向键上下左右移动。点击方向键时移动正常,但想实现按住方向键持续移动、抬手即停的效果。当前使用的代码如下:

void Update()
{

    if (Input.GetKey(KeyCode.DownArrow))
    {
        direction = 2;
    }
    if (Input.GetKey(KeyCode.LeftArrow))
    {
        direction = 3;
    }
    if (Input.GetKey(KeyCode.UpArrow))
    {
        direction = 4;
    }
    if (Input.GetKey(KeyCode.RightArrow))
    {
        direction = 1;
    }
    if (Input.GetKeyUp(KeyCode.DownArrow) ||
        Input.GetKeyUp(KeyCode.LeftArrow) ||
        Input.GetKeyUp(KeyCode.UpArrow) ||
        Input.GetKeyUp(KeyCode.RightArrow))
    {
        direction = 0;
    }
    movePacman();
}

private void movePacman()
{  
    switch (direction)
    {
        case 1:
            moveRight();              
            break;
        case 2:
            moveDown();              
            break;
        case 3:
            moveLeft();               
            break;
        case 4:
            moveUp();              
            break;
        default:
            break;
    }
}

目前遇到的问题:若不快速松开按键,角色有时会连续移动两次,请问该如何解决?


问题原因

原代码中Update每帧都会调用movePacman,如果moveRight/moveLeft等方法是瞬间移动一格(直接修改位置到目标格子),按住按键时每帧执行一次移动会导致速度过快,且松开按键时可能因输入帧的延迟,最后一帧仍执行了移动操作,出现“连续移动两次”的错觉。

解决方案

方案1:计时器控制格子移动间隔(适合吃豆人式逐格移动)

添加计时器变量,固定每间隔一段时间才移动一次,避免每帧重复触发:

private float moveTimer;
public float moveInterval = 0.2f; // 移动间隔,值越小移动越快

void Update()
{
    // 优先处理方向输入
    if (Input.GetKey(KeyCode.DownArrow))
    {
        direction = 2;
    }
    else if (Input.GetKey(KeyCode.LeftArrow))
    {
        direction = 3;
    }
    else if (Input.GetKey(KeyCode.UpArrow))
    {
        direction = 4;
    }
    else if (Input.GetKey(KeyCode.RightArrow))
    {
        direction = 1;
    }
    else
    {
        // 无按键按住时重置方向和计时器
        direction = 0;
        moveTimer = 0;
        return;
    }

    // 累加计时器,达到间隔才移动
    moveTimer += Time.deltaTime;
    if (moveTimer >= moveInterval)
    {
        movePacman();
        moveTimer = 0; // 重置计时器
    }
}

private void movePacman()
{  
    switch (direction)
    {
        case 1:
            moveRight();              
            break;
        case 2:
            moveDown();              
            break;
        case 3:
            moveLeft();               
            break;
        case 4:
            moveUp();              
            break;
        default:
            break;
    }
}

方案2:改为平滑持续移动(适合平台跳跃式平滑位移)

如果你的角色需要平滑移动而非逐格跳跃,修改move系列方法,用Time.deltaTime控制移动速度,同时简化输入逻辑:

首先修改移动方法:

public float moveSpeed = 5f; // 调整移动速度

private void moveRight()
{
    transform.Translate(Vector2.right * moveSpeed * Time.deltaTime);
}

private void moveLeft()
{
    transform.Translate(Vector2.left * moveSpeed * Time.deltaTime);
}

private void moveUp()
{
    transform.Translate(Vector2.up * moveSpeed * Time.deltaTime);
}

private void moveDown()
{
    transform.Translate(Vector2.down * moveSpeed * Time.deltaTime);
}

然后简化Update逻辑:

void Update()
{
    direction = 0; // 默认无方向
    if (Input.GetKey(KeyCode.DownArrow))
    {
        direction = 2;
    }
    else if (Input.GetKey(KeyCode.LeftArrow))
    {
        direction = 3;
    }
    else if (Input.GetKey(KeyCode.UpArrow))
    {
        direction = 4;
    }
    else if (Input.GetKey(KeyCode.RightArrow))
    {
        direction = 1;
    }

    movePacman();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:36:19