2D俯视角角色撞墙时动量持续累积的问题修复咨询
问题描述
角色移动包含加速/减速过程,使用两个初始值为0、最大值为1的float变量计算移动速度,核心代码如下:
Update方法代码
private void Update() { float moveTowardsX = 0; float moveTowardsY = 0; // 限制推力不超过最大值 if(thrust >= maxThrust) { thrust = maxThrust; } // 计算每秒速度变化率 float changeRatePerSecond = 1 / timeFromZeroToMax * thrust * Time.deltaTime; changeRatePerSecond /= weight / 1.5f; if(onMobile == true) { // 移动端输入处理 if(isMovingLeft == true && isMovingRight == false) { moveTowardsX = -1.0f; } else if(isMovingRight == true && isMovingLeft == false) { moveTowardsX = 1.0f; } if(isMovingUp == true && isMovingDown == false) { moveTowardsY = 1.0f; } else if(isMovingDown == true && isMovingUp == false) { moveTowardsY = -1.0f; } if(isRotatingLeft == true && isRotatingRight == false) { rotationsPerSecond++; } else if(isRotatingRight == true && isRotatingLeft == false) { rotationsPerSecond--; } } }
FixedUpdate移动处理代码
void FixedUpdate() { // 平滑过渡目标值 valueX = Mathf.MoveTowards(valueX, moveTowardsX, changeRatePerSecond); valueY = Mathf.MoveTowards(valueY, moveTowardsY, changeRatePerSecond); // 应用移动速度 rb.velocity = new Vector2(valueX * runSpeed, valueY * runSpeed); }
当前问题:角色撞墙时,valueX/valueY不会下降;静止状态下撞墙,数值反而上升。
解决方案
核心问题是逻辑变量与物理引擎状态完全脱节,强行用valueX/valueY覆盖刚体速度,导致碰撞反馈无法同步到逻辑数值。以下是三种可行修复方案:
1. 同步物理速度到逻辑变量
每次FixedUpdate时,先将刚体实际速度反向映射到valueX/valueY,再进行平滑过渡,保证逻辑与物理状态一致:
void FixedUpdate() { // 同步物理速度到逻辑变量 valueX = rb.velocity.x / runSpeed; valueY = rb.velocity.y / runSpeed; // 基于输入平滑调整目标值 valueX = Mathf.MoveTowards(valueX, moveTowardsX, changeRatePerSecond); valueY = Mathf.MoveTowards(valueY, moveTowardsY, changeRatePerSecond); // 应用调整后的速度 rb.velocity = new Vector2(valueX * runSpeed, valueY * runSpeed); }
撞墙时物理引擎会重置刚体速度,valueX/valueY会同步下降,不会出现数值异常。
2. 碰撞时直接修正逻辑变量
在碰撞回调中检测碰撞对象与方向,直接重置对应方向的逻辑数值:
private void OnCollisionEnter2D(Collision2D collision) { // 判定碰撞对象为墙(根据实际标签修改) if(collision.gameObject.CompareTag("Wall")) { Vector2 collisionNormal = collision.contacts[0].normal; // 左右方向碰撞,重置X轴数值 if(Mathf.Abs(collisionNormal.x) > 0.5f) { valueX = 0; } // 上下方向碰撞,重置Y轴数值 if(Mathf.Abs(collisionNormal.y) > 0.5f) { valueY = 0; } } }
该方案需准确配置碰撞标签与方向判断,适合场景碰撞体规则明确的情况。
3. 改用AddForce驱动移动
放弃直接设置velocity,改用AddForce实现平滑加速,让物理引擎自动处理碰撞减速:
void FixedUpdate() { // 计算目标速度 Vector2 targetVelocity = new Vector2(moveTowardsX * runSpeed, moveTowardsY * runSpeed); // 计算平滑过渡的速度增量 Vector2 velocityDelta = Vector2.MoveTowards(rb.velocity, targetVelocity, changeRatePerSecond) - rb.velocity; // 施加力实现平滑加速 rb.AddForce(velocityDelta, ForceMode2D.Force); }
该方案完全依托Unity物理系统,碰撞减速会自动处理,逻辑更简洁,需调整参数匹配原有操作手感。
内容的提问来源于stack exchange,提问作者ljksfenfkljbakfkja
相关产品推荐
相关产品推荐

