Vehicle_Base拆分
仅用作个人整理或买了插件的童鞋学习分享插件地址
一、EventBeginPlay
1.1、参数初始化
InitAll
1.2、定时更新数据
单独作为第二节进行
二、每隔0.04s一次更新——25TPS
25TPS即为每秒更新25帧,限制更新频率来更好地进行多端同步
车辆前进后退的基础逻辑没有在里面,先不总结就放出来了,我再去别的逻辑里找找
目前怀疑该插件完全使用轮胎进行驱动,恐怖如斯
2.1 UpdateInput
三个逻辑都是定时Lerp当前值到同步下来的指定值。而Thottle直接Lerp,Brake有辅助赋值,Steer由玩家输入、SteerCurve、Slip共同决定,三个参数都有限制保证最终Steer处于0-1区间
主要逻辑:
- 设置Throttle,由D Throttle Lerp出来
- 设置Brake,由D Brake Lerp出来
- 设置IsBrakeApply,由Brake!=0决定
- 设置BrakeChanged,由Brake状态是否转变决定
- 设置CurSteering,由DSteering*Clamp(SteerCurve+Slip,0,1)决定
约束关系:
对玩家主要上下左右输入都进行了Lerp
CurSteer主要受Steer曲线和Slip影响,但都被限制到0-1区间
- Throttle = Lerp D Throttle
- Brake = Lerp D Brake
- BrakeChanged = Brake != IsBrakeApply
- IsBrakeApply = Brake != 0
- CurSteering = Lerp Clamp( (SteerForSpeedCurve+Slip),0,1)*D Steer
2.1.1 CaluclateThrottle
2.1.2 Calculate Brakes
2.1.3 Calculate Steering
由该代码知:转向与SteerCurve以及Slip有关,但上下值都有限制
2.2 EngineSimulate
核心逻辑:
- 设置CurThrottle为Throttle的平滑过渡
- 由汽车运行数据计算AirSpeed、Acceleration、AverageWheelSpeed
- 由玩家输入作为百分比确定TarSpeed(Start-EndSpeed)
- 根据不同情况设置SelectedGear,并在指定时间后切换到该Gear,初始化MaxTorque为MaxTorque
- 根据AverageWheelSpeed所在区间比值设置对应RPM,并由Throttle进行-1000到1000的区间调整
- 根据当前速度调整Torque,速度越大Torque越小。
- 如果引擎没有开启的话则设TarSpeed、Torque为0,MPR Lerp到0
约束关系
- CurThrottle ≈ Throttle
- AirSpeed = MeshLinearSpeed
- Acce = AirSpeed - OldAirSpeed
- AverageWheelSpeed = WheelsRotationSpeed / WheelsNum
- TargetSpeed = CurThrottle * (End-StartSpeed)
- CurGear = Gear.MaxTorque
-
- 停车:-1 | 倒车:0 | 换挡:-1
-
- AirSpeed > EndSpeed:CurGear++
-
- AirSpeed < StartSpeed:CurGear–
- Gear = Gears[CurGear]
- RPM=(Speed区间内AverageWheelSpeed 比例) 映射到RPM + Throttle[0,1]映射到[-1000, 1000]
- Torque=(1 - AirSpeed在Start/EndSpeed的比例)映射到[MaxTorque,MinTorque]
计算汽车基本参数
2.2.1 设置CurrentThrottle
2.2.2 Calculate Speed
约束关系:
- AirSpeed=MeshLinearVelocity
- Acceleration=(curSpeed-oldSpeed)*25
- AverageWheelSpeed=WheelNum / WheelsRotatorSpeed
简单地计算车身速度、加速度、轮子旋转速度
2.2.3 Calculate Speed Target
约束关系:
TargetSpeed与玩家输入直接相关,玩家不输入就是StartSpeed,输入就是EndSpeed
- TarSpeed=CurThrottle*(StartSpeed-EndSpeed)+EndSpeed
2.2.4 Transmission
CurGear仅仅是Gear切换标记,真正的数值都存在Gear里且不一定与CurGear同步。
主要逻辑:
自动换挡
- 前进时根据AirSpeed在DownShift和UpShift范围外进行升降档
- 后退使用0档,停车使用-1档
手动换挡
- 直接切到对应挡位
换挡时
- 除了-1档其他都需要等待GearSwitchTime,期间CurGear变为-1,Gear数值变为换挡时的特殊值。
- 换挡后DynamicMaxTorque被初始化为MaxTorque
约束关系:
SelectGear:
- Shifter == Park/Neutral :-1
- Shifter == Reverse:0
- Shifter == Drive:
-
- AirSpeed < Gear.DownShift:++1
-
- AirSpeed > Gear.UpShift:- -1
CurGear:
- 挡位切换时期:-1
- 切换后:SelectGear
Gear:
- 挡位切换后:Gears[CurGear]
DynamicMaxTorque:
- 挡位切换后:Gear.MaxTorque
挡位切换时间=SwitchGearTime
a) 自动换挡:
当前为设置SelectedGear
- Park和Neutura时=-1,倒车时为0(Choose N Gear、Choose R Gear)
- 前进时通过AirSpeed是否在DownShift和UpShift之间决定升降档(Choose D Gear)
- 除了降到-1档,其他都按照GearSwitchTime进行Timer换挡函数调用(Schedule Gear Change)
当前为设置CurGear
- 在换挡期间CurGear==-1档,Gear被设置为换挡期间专用参数,但最低MPR为0档的MPR(ApplyNGear)
- 换挡时设置CurGear+Gear,同时初始化DynamicMaxTorque为MaxTorque
D Gear
通过判断ShiftUp和ShiftDown进行自动换挡
Schedule Gear Change
ChangeGear
ApplyNGear
换挡期间CurGear为-1,且重设Gear的数值如下:
b) 手动换挡:
直接执行ChangeGear
2.2.5 Calculate Engine RPM
步骤:
- 计算车辆速度在当前挡位的比值GearThresh
- 将该比值对应出相应的RPM数值 RPM1
- 玩家输入Throttle(0 — 1)对应RPM2(-1000 — +1000)
- D RPM=RPM1+RPM2
- Lerp RPM
约束关系:
速度与RPM为正比,同时一定范围内受到Throttle影响
- D RPM=(EndSpeed — StartSpeed区间内AverageWheelSpeed 所占比例) * (HightRPM - LowRPM) + LowRPM + Throttle*2000 - 1000
- RPM=Lerp D RPM
2.2.6 Calculate Torque
步骤
- 通过MAcce-Acce计算动态MaxTorque,每次maxTorque增减<1
- AirSpeed离StartSpeed越远扭矩越小。速度过慢扭矩=0,速度过快扭矩=MinTorque
- 如果没有处于前进/后退,则Torque=0
约束关系:
加速度越不接近MaxAcce则MaxTorque越大
扭矩与当前车速成反比
- MaxTorque=AccelerationConfig?9000 : clamp(MaxAcce-Acce,-1,1)
- Torque=(1 - AirSpeed在Start/EndSpeed的比例)*(MaxTorque-MinTorque)
VehicleInGear
当汽车正在前进/后退时为InGear
Calculate Max Torque
TorqueCurve
2.2.7 Engine Off
- 引擎关闭时运行
- 将TarSpeed/Torque直接置为0,RPM Interpto 0
2.3 UpdateForces
主要用于更新轮胎的旋转阻尼以及汽车的线性阻尼,但阻尼参数都被写死了
步骤
- 根据当前速度是否超过了挡位最高速度来计算EngineBrake的值
- 比较计算后的引擎Brake、Brake,取最大值设置车轮的AngularDamping
- 将汽车左右朝向的速度[1000-2000]映射到Slip[0-1]
- 汽车线性阻尼为Slip与动态空气阻力LinearDrag相加
- 当车速过慢且没有Throttle时,增大阻尼来达到停车效果
- 当Slip<0.1时忽略Slip的阻尼效果,只有LinearDrag
约束
- EngineBrake=[EndSpeed,EndSpeed+(EndSpeed-StartSpeed)]映射[0,1]
- Wheels.AngularDamping=Max(EnginBrake20 , BrakeBrakePressure)
- Slip=VehicleMesh.RightSpeed[1000,2000]映射[0,1]
- VehicleMesh.LinearDamping=Slip[0,1]->[0.02,0.25]+LinearDrag
2.3.1 Calculate Engine Brake
步骤:
- 判断AirSpeed是否超过了EndSpeed
- 如果超过了,则设置EngineBrake,其值映射:[EndBrake,EndBrake+(End-StartSpeed)]—[0-1]
约束
- EngineBrake=[EndBrake,EndBrake+(End-StartSpeed)]映射为 [0-1]
2.3.2 Apply Brakes
步骤:
- 计算BrakeBrakePress和EngineBrake20的值,得出的最大值为轮胎的角速度阻尼
- 当Brake>0.96以及速度过低后锁住轮胎
约束:
- Wheels.AngularDamping
2.3.3 Calculate Slip
步骤:
- 将汽车左右朝向的速度[1000-2000]映射到Slip[0-1]
约束
- Slip=MeshRightVelocity in [1000,2000]映射[0,1]
2.3.4 Apply Air Drag
主要通过LinearDrag动态空气阻力来设置汽车对应的线性阻尼
步骤
AirSpeed速度慢:
- 附加大阻尼导致停车
AirSpeed速度快:
- 设置阻尼为Slip[0-1][0.02-0.25]+LinearDrag(动态空气阻力值,DynamicAirDrag=true时启用)
- 如果Slip<=0.1,则忽略Slip
约束
- VehicleMesh.LinearDamping=
-
- AirSpeed < 0.3:30
-
- AirSpeed >= 0.3:( Slip[0-1] 映射 [0.02 , 0.25] ) + LinearDrag
-
-
- 当Slip<0.1时,忽略Slip
-
2.4 TickWheels
处理车轮的Mesh旋转、特效、声音
疑问的点在于WheelConstrain是否会影响逻辑
步骤:
- 设置Wheel的CurSteering为车辆的CurSteering
- 通过TarSpeed设置轮胎转速
- 当需要Skid粒子或声音时根据DesiredSkid Lerp Skid值并根据Skid值播放声音
- 根据Steering设置轮胎Yaw轴的旋转值
约束:
- Wheel.CurSteering = CurSteering
- WheelConstrain.AngularVelocityTarget = TarSpeed * 44.704 / wheel.perimeter
- WheelConstrain.VelocityStrength=Torque (???)
- Skid = Lerp DesiredSkid
- RotationSpeed = MeshAngularVelocity * radius * UnitConversion
- WheelMesh.Rotation=Steering*MaxSteeringAngle
2.4.1 Update Steering
放到了Wheel类中处理
步骤:
- 设置Wheel的Steering为对应的CurSteering
- 如果不是转向轮则不设置,如果轮胎反转则*-1
约束
- Wheels.CurStreeing = CurStreeing
a) Vehicle_Wheel.SetSteering()
2.4.2 Update Torque
步骤:
- SetVehicleTorque(TarSpeed,Torque)
1.1. 如果不是DrivingWheel的话不用管Torque
1.2. 如果正在停车/轮胎锁住/超过最大速度/CurGear=-1的话,SetTorque(0,0) - 通过TarSpeed算出对应轮胎Mesh的转速,TarSpeed与转速成正比。通过Torque设置轮胎的VelocityStrenth???
约束:
- WheelConstrain.AngularVelocityTarget = TarSpeed * 44.704 / wheel.perimeter
- WheelConstrain.VelocityStrength=Torque (???)
a) Vehicle_Wheel.SetVehicleTorque
b) Vehicle_Wheel.SetWheelTorque
通过MPH以及轮胎直径计算出转速,然后SetAngularVelocityTarget,不太懂将扭矩设置给DriveParams
求半径:GetBounds() / GetBOdyBounds() * scale
单位换算:1mph=44.704 cm/s = 1.609km/h
2.4.2 Update Wheel
步骤:
- 设置Skid为DesiredSkid的Lerp
- 清除Skid特效(代码中并没有明显开启特效的代码)
- 通过WheelMesh的Velcity以及当前单位计算出当前RotationSpeed
- 根据Steering设置轮胎的Steering旋转
约束:
- Skid = Lerp DesiredSkid
- RotationSpeed = MeshAngularVelocity * radius * UnitConversion
- WheelMesh.Rotation=Steering*MaxSteeringAngle
a) UpdateSkid
b) CleanupSkidParticle
c) Update RotationSpeed
通过角速度来Update轮胎的RotationSpeed
D) SteeringRotator + SetRelativeRotator
根据CurSteering转动轮胎Yaw轴角度
2.4.3 Tick Cosmetic
根据RPM和Throtle更新尾气的粒子效果