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物理系统的运行逻辑。
修复方案与代码实现
核心修改点
- 输入处理优化:用
GetKey检测持续按键状态,自动处理松开后的状态复位 - 保留重力效果:仅修改velocity的X轴分量,Y轴保留Rigidbody2D的重力影响
- 物理帧同步:将移动逻辑移至
FixedUpdate(Unity物理更新帧),保证物理操作的稳定性 - 跳跃逻辑修正:直接设置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
相关产品推荐
相关产品推荐

