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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:35:20