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

飞行模拟控制器油门加速/减速逻辑实现技术咨询

飞行模拟控制器油门逻辑实现优化

需求说明

  • 油门无怠速状态,仅包含0(关闭)和最大速度两种状态切换逻辑
  • 油门输入值范围为-1至1:
    • 当输入值> -1时,速度开始提升;-1~0区间对应速度范围0~650,0~1区间对应速度范围650~1390
    • 油门值越高,加速度越大;减速过程保持恒定减速度

当前试错代码

void SetThrust()
{
     var revisionValue = throttle + 1;
     var outputRate = (revisionValue - 0) / (2 - 0) * 100;

     if (throttle > -1f)
     {
        //add some smooth or lerp increase * decrease speed amount
        increment = outputRate * throttleFactor;
        speedEase = (maxThrust - thrust) * speedReciprocal;
     }

     // Some logic for item2 (increase/decrease speed according to the input value))       
}


void CalulateMovement()
{
    float gravityFallByPitch = gravityAngularFactor * Mathf.Sin(transform.eulerAngles.x * Mathf.Deg2Rad);

    rotateValue = new Vector3(pitch * pitchFactor - gravityFallByPitch, yaw * yawFactor, roll * (rollFactor * Mathf.Abs(roll)));
    lerpRotate = Vector3.Lerp(lerpRotate, rotateValue, lerpFactor * Time.fixedDeltaTime);

    transform.Rotate(lerpRotate * Time.fixedDeltaTime);

    if (throttle > -1f)
    {
        if (m_rigidbody.IsSleeping())
            m_rigidbody.WakeUp();

        gravityFallByPitch = gravitySpeedFactor * Mathf.Sin(transform.eulerAngles.x * Mathf.Deg2Rad);
        thrust = (increment+gravityFallByPitch) * speedEase;
        thrust = Mathf.Clamp(thrust, minThrust, maxThrust);
        m_rigidbody.AddForce(transform.forward * thrust);
    }

    else if (throttle <= -1f && m_rigidbody.velocity.magnitude <= 1)
    {
        m_rigidbody.velocity *= 0;
        m_rigidbody.Sleep();
    }
}

问题分析

当前代码将加速度计算与速度缓动逻辑混合,导致加减速逻辑冲突。核心问题是没有明确区分目标速度区间和对应加速度规则,无法精准控制不同油门区间的加速度上限。

计算方法与优化思路

1. 明确目标速度映射

先将油门输入值分段映射到对应的目标速度区间:

float GetTargetSpeed(float throttle)
{
    if (throttle <= -1f)
        return 0f;
    else if (throttle <= 0f)
        // -1~0 对应 0~650:throttle+1 从0到1,线性映射
        return 650f * (throttle + 1f);
    else
        // 0~1 对应 650~1390:throttle从0到1,线性映射
        return 650f + (1390f - 650f) * throttle;
}

2. 分离加减速逻辑

  • 加速阶段:根据油门值计算加速度,油门越高加速度越大。例如将油门值映射为加速度系数,乘以最大加速度得到当前加速度:
    // 加速度系数:-1时为0,1时为1,线性变化
    float accelFactor = Mathf.InverseLerp(-1f, 1f, throttle);
    float currentAcceleration = maxAcceleration * accelFactor;
    
  • 减速阶段:当当前速度超过目标速度时,使用恒定减速度:
    float deceleration = constantDeceleration; // 自定义恒定减速度值
    

3. 基于目标速度的推力控制

直接根据当前速度与目标速度的差值,结合加减速规则计算推力,避免逻辑混淆:

void UpdateThrust()
{
    float targetSpeed = GetTargetSpeed(throttle);
    float currentSpeed = m_rigidbody.velocity.magnitude;
    float speedDiff = targetSpeed - currentSpeed;

    float desiredAcceleration;
    if (speedDiff > 0)
    {
        // 加速:按油门值对应加速度
        float accelFactor = Mathf.InverseLerp(-1f, 1f, throttle);
        desiredAcceleration = maxAcceleration * accelFactor;
    }
    else
    {
        // 减速:恒定减速度
        desiredAcceleration = -constantDeceleration;
    }

    // 计算所需推力(考虑重力俯仰影响)
    float gravityFallByPitch = gravitySpeedFactor * Mathf.Sin(transform.eulerAngles.x * Mathf.Deg2Rad);
    float requiredThrust = (desiredAcceleration + gravityFallByPitch) * m_rigidbody.mass;
    requiredThrust = Mathf.Clamp(requiredThrust, 0f, maxThrust);

    if (throttle > -1f)
    {
        if (m_rigidbody.IsSleeping())
            m_rigidbody.WakeUp();
        m_rigidbody.AddForce(transform.forward * requiredThrust);
    }
    else
    {
        // 油门关闭,停止并休眠刚体
        if (currentSpeed <= 1f)
        {
            m_rigidbody.velocity = Vector3.zero;
            m_rigidbody.Sleep();
        }
        else
        {
            // 未完全停止时,用恒定减速度减速
            m_rigidbody.AddForce(-transform.forward * constantDeceleration * m_rigidbody.mass);
        }
    }
}

4. 其他优化点

  • 用Mathf.InverseLerp替代手动区间计算,代码更简洁且不易出错
  • 将加减速参数(maxAcceleration、constantDeceleration)暴露为可调试的变量,方便调整手感
  • 分离旋转与推力控制逻辑,保持函数职责单一
  • 避免直接修改velocity,优先用AddForce实现物理驱动,保证物理系统稳定性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:21:02