Unity2D集成Netcode后实例化RigidBody2D动量异常求助
Unity2D Netcode 移动异常问题修复
问题描述
Unity2D新手使用Netcode for GameObjects实现多人联机后,预制体移动异常:按住A键时动量始终为0,按住D键时动量固定在1.5,跳跃功能正常,已用Debug.Log排查但未定位根源。注:speed参数由预制体内的Stats.cs脚本设置。
错误代码
using Unity.Netcode; using System.Runtime.CompilerServices; using UnityEngine; using UnityEngine.UI; public class PlayerMovement : NetworkBehaviour { //Only To Monitor Motion public float momentum; public float horizontal; public float vertical; //Character Stats public float speed; public float jumpingPower; private bool canJump; private int dbJump; private float baseSpeed; public bool isGrounded; public Rigidbody2D rb; [SerializeField] private Transform groundCheck1; [SerializeField] private Transform groundCheck2; [SerializeField] private Transform groundCheck3; [SerializeField] private LayerMask groundLayer; public bool isFacingRight = true; //KB Check private Knockback kb; private void Start() { kb = GetComponent<Knockback>(); dbJump = 0; canJump = true; horizontal = 0; baseSpeed = speed; isGrounded = true; } void Update() { if (!IsOwner) return; if (rb.linearVelocityY <= -61 && !Input.GetKey(KeyCode.S)) { rb.linearVelocityY += (rb.linearVelocityY + 60) * -1; } if (dbJump == 0) { canJump = false; } if (IsGrounded()) { canJump = true; dbJump = 1; } if (IsOwner) { horizontal = Input.GetAxisRaw("Horizontal"); if (horizontal == 1 && momentum <= speed) { Debug.Log("horizontal 1 detected"); if (horizontal == 1 && momentum <= 0) { momentum += 1.5f; Debug.Log("Momemtum ++"); } momentum += baseSpeed * 0.05f; Debug.Log("Momemtum +"); if (momentum > speed) { momentum = speed; } } else if (horizontal == -1 && momentum >= (speed * -1)) { Debug.Log("horizontal -1 detected"); if (horizontal == 1 && momentum >= 0) { momentum -= 1.5f; Debug.Log("Momemtum --"); } momentum -= baseSpeed * 0.05f; Debug.Log("Momemtum -"); if (momentum < speed * -1) { momentum = speed*-1; } } else if (horizontal == 0) { Debug.Log("horizontal 0"); if (momentum > 0.4f) { momentum -= 0.75f; } else if (momentum < -0.4f) { momentum += 0.75f; } else if (!Input.GetKeyDown(KeyCode.D)&& !Input.GetKeyDown(KeyCode.A)) { momentum = 0; } } if ((Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.Space)) && canJump) { rb.linearVelocity = new Vector2(rb.linearVelocity.x, jumpingPower); dbJump -= 1; } if ((Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.Space)) && rb.linearVelocity.y > 0f) { rb.linearVelocity = new Vector2(rb.linearVelocity.x, rb.linearVelocity.y * 0.5f); } Flip(); } if (vertical != 0) { isGrounded = false; } else { isGrounded = true; } } private void FixedUpdate() { vertical = rb.linearVelocity.y; rb.linearVelocity = new Vector2(momentum, rb.linearVelocity.y); if (Input.GetKey(KeyCode.S) && vertical > -117.70f) { rb.linearVelocity = new Vector2(momentum, rb.linearVelocity.y - 5); } else if (Input.GetKey(KeyCode.S) && vertical < -117.70f) { rb.linearVelocity = new Vector2(momentum, -117.7f); } if ((Input.GetKeyUp(KeyCode.S) && rb.linearVelocity.y < -60)) { rb.linearVelocity = new Vector2(momentum, -60); } } private bool IsGrounded() { return Physics2D.OverlapCircle(groundCheck1.position, 0.2f, groundLayer)|| Physics2D.OverlapCircle(groundCheck2.position, 0.2f, groundLayer) || Physics2D.OverlapCircle(groundCheck3.position, 0.2f, groundLayer); } public void Flip() { if (isFacingRight && horizontal < 0f || !isFacingRight && horizontal > 0f) { isFacingRight = !isFacingRight; Vector3 localScale = transform.localScale; localScale.x *= -1f; transform.localScale = localScale; } } }
问题根源及修复方案
1. 左移分支逻辑错误
左移代码块内的判断条件写错,horizontal == 1永远无法成立(此时horizontal为-1),导致左移时无初始动量变化,修正如下:
else if (horizontal == -1 && momentum >= (speed * -1)) { Debug.Log("horizontal -1 detected"); // 修正匹配左移的判断条件 if (horizontal == -1 && momentum >= 0) { momentum -= 1.5f; Debug.Log("Momemtum --"); } momentum -= baseSpeed * 0.05f; Debug.Log("Momemtum -"); if (momentum < speed * -1) { momentum = speed*-1; } }
2. 基础速度未正确赋值
Start()中baseSpeed = speed;依赖Stats.cs对speed的赋值,需确保Stats.cs在Awake/Start阶段主动给PlayerMovement的speed赋值,例如:
// 在Stats.cs的Awake或Start中添加 void Awake() { GetComponent<PlayerMovement>().speed = 你的目标速度值; }
若baseSpeed为0,会导致按住D键时动量仅能增加初始的1.5,后续无法提升;左移时动量无变化,始终为0。
3. 停止逻辑优化
原代码中horizontal == 0分支的按键判断逻辑错误(GetKeyDown仅检测瞬间按下),简化为直接归0:
else if (horizontal == 0) { Debug.Log("horizontal 0"); if (momentum > 0.4f) { momentum -= 0.75f; } else if (momentum < -0.4f) { momentum += 0.75f; } else { momentum = 0; } }
4. 移除冗余权限判断
Update开头已有if (!IsOwner) return;,后续无需重复判断if (IsOwner),避免逻辑混乱。
验证步骤
- 修正上述代码后,运行游戏测试左右移动
- 用Debug.Log输出
baseSpeed和momentum的值,确认速度参数正确赋值 - 检查Netcode的玩家对象Owner权限是否正确分配
内容的提问来源于stack exchange,提问作者Liam
相关产品推荐
相关产品推荐

