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

Unity单人键盘本地多人2D平台游戏Rigidbody2D运动异常求助

Unity单键盘本地多人2D平台游戏Rigidbody2D问题修复

问题概述

开发基于Unity的单键盘本地多人2D平台游戏时,遇到两个核心问题:

  • 同一客户端的WASD和方向键两组输入无法正常生效,角色移动状态易卡住
  • 角色跳跃后悬浮在空中,代码直接覆盖Rigidbody2D重力导致无法下落;尝试Thread.Sleep(Unity无效)、协程模拟重力均失败

原代码问题分析

输入逻辑缺陷

两个移动脚本(MoveArrows/MoveWASD)仅用GetKeyDown检测按键按下瞬间,未处理按键松开后的状态重置,导致MovementX/Y值在按键松开后保持不变,角色持续处于移动状态。

重力覆盖问题

每帧Update中直接给rigidBody.velocity赋值固定值,完全覆盖了Rigidbody2D自带的重力物理效果,角色失去自然下落的动力。

协程使用错误

尝试的协程未在延迟后执行重力逻辑,而是启动协程后立刻设置MovementY=-1,没有等待协程完成;且手动模拟重力的方式不符合Unity物理系统的运行逻辑。

修复方案与代码实现

核心修改点

  1. 输入处理优化:用GetKey检测持续按键状态,自动处理松开后的状态复位
  2. 保留重力效果:仅修改velocity的X轴分量,Y轴保留Rigidbody2D的重力影响
  3. 物理帧同步:将移动逻辑移至FixedUpdate(Unity物理更新帧),保证物理操作的稳定性
  4. 跳跃逻辑修正:直接设置velocity的Y分量为跳跃力,让重力自然作用于下落过程

修改后的MoveArrows脚本

using UnityEngine;

public class MoveArrows : MonoBehaviour
{
    public float moveSpeed = 5f;
    public float jumpForce = 7f;
    private Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void FixedUpdate()
    {
        // 水平移动:仅修改X轴速度,保留Y轴重力效果
        float moveX = 0;
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            moveX = -1;
        }
        else if (Input.GetKey(KeyCode.RightArrow))
        {
            moveX = 1;
        }
        rb.velocity = new Vector2(moveX * moveSpeed, rb.velocity.y);
    }

    void Update()
    {
        // 跳跃检测放在Update,保证输入响应及时
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            // 可添加地面检测逻辑防止二段跳,此处简化处理
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
        }
    }
}

修改后的MoveWASD脚本

using UnityEngine;

public class MoveWASD : MonoBehaviour
{
    public float moveSpeed = 5f;
    public float jumpForce = 7f;
    private Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void FixedUpdate()
    {
        float moveX = 0;
        if (Input.GetKey(KeyCode.A))
        {
            moveX = -1;
        }
        else if (Input.GetKey(KeyCode.D))
        {
            moveX = 1;
        }
        rb.velocity = new Vector2(moveX * moveSpeed, rb.velocity.y);
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
        }
    }
}

额外优化建议

  • 添加地面检测:通过射线或触发器判断角色是否在地面,避免二段跳
  • 调整参数:根据游戏手感修改moveSpeed和jumpForce数值
  • 平滑移动:加入加速度/减速度逻辑,让角色移动更自然

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:10:23