表面轮胎形变
轮胎形变
受载的轮胎不会保持圆形。在与地面接触处,它向两侧鼓起,在接触点凹陷,车辆压得越重,轮胎被压扁得越厉害。插件把这种效果绘制在车辆的车轮网格体上,因此轮胎无论在哪种地面上都显得承受着负载。压在圆形障碍物(例如横杆、原木或路缘石的圆角边缘)上的轮胎会包裹住它,车轮则会离开障碍物,使轮辋留在外面。本页介绍决定这种效果的配置文件、决定哪些轮胎会发生形变的预算,以及如何设置两者。
车辆的每个车轮,只要预算允许,都会获得一个轮胎形变器。形变器追踪轮胎下方的地面,并把接触信息写入车轮网格体,轮胎材质则根据这些接触绘制鼓起效果。预算未授予的轮胎不会获得形变器,也不会鼓起。你自己车辆的轮胎始终会形变;其他车辆的轮胎则在靠近摄像机并处于预算上限之内时形变。
- 接触。 轮胎用一组扇形射线追踪地面。Num Arc Samples 条射线横穿接触弧,Num Lateral Rows 行射线横穿胎面。每个接触都写入车轮网格体的自定义基元数据,共 32 个浮点数,由
MF_CF_TireDeform读取。M_CF_TireDeform是使用它的轮胎材质。 - 深度。 Max Deflection 限制最深凹陷,单位厘米。凹陷会随时间增长和消退,速度分别由 Depth Grow Speed 和 Depth Fade Speed 决定。
- 障碍物。 当射线扇形打到圆形障碍物时,轮胎根据相邻的三个命中点读出它在车轮平面内的曲率,轮胎材质则把轮胎压进这个圆里,边缘是圆滑的。只有当三个命中点的法线与这个圆一致时,这个圆才会被采用,所以平坦的地面和路缘石的尖角仍然使用平面压入。比 Min Obstacle Radius 更细的障碍物,按这个粗细压入。距离相近的命中点只有在法线相差不超过 Merge Angle Deg 时才合并为一个接触;取值过低时,大轮胎下的小圆形障碍物会占满四个接触点,地面就失去了自己的接触点。
- 推挤。 轮胎一直凹陷,直到障碍物与轮辋之间只剩下 Rubber Margin 厚的橡胶。再深的部分,它会请求宿主把整个车轮从障碍物移开,最多移开 Max Push,剩下的部分由凹陷承担。推挤量以
FCFTireWheelOffset::PushCm交给宿主,前提是宿主接受它(FCFTireWheelDesc::bAcceptsPush)。两个适配器都接受。覆盖了 Set Crushform Tire Wheel Offsets 的蓝图自行摆放车轮:此时不会计算推挤,轮胎像没有推挤时那样凹陷,最深到 Max Deflection,轮辋可能嵌入障碍物。轮辋半径取自轮胎材质的RimRadius参数,或取自配置文件中的 Rim Radius Override。两者都没有的车轮从不被推挤。 - 负载。 车辆会报告每个轮胎的接触力相对其标称负载的比值。轮胎的负载系数趋向
1 + Load Sensitivity * (ratio - 1),并限制在 0 与 Max Load Factor 之间。负载较重的一角会把轮胎压得更扁。静止的轮胎被压扁 Resting Deflection,即其半径的一个比例。 - 预算。 Scope 设置决定哪些轮胎形变。
RigOnly只让观察者自己的车辆形变。Budgeted(默认)在此基础上加入半径内其他车辆的轮胎,按屏幕内优先、距离近优先的顺序,最多为 Max Wheels 个车轮。Unlimited不设预算,给每个轮胎完整的细节。观察者的车辆组合,即它的车辆及与之耦合的一切,始终会形变,即使超过上限也是如此。Pawn 通过ICFTireViewer说明自己乘坐的是哪辆车。预算的各项值是项目设置,每一项都有一个会覆盖它的控制台变量;见 项目设置 和 性能。 - 细节。 离摄像机比 Lod Distance 1 更远的轮胎使用更稀疏的扇形射线;超过 Lod Distance 2 后,则使用最稀疏的扇形,并与简单碰撞进行检测。
- 休眠。 已停稳、且保持在距静止姿态 Sleep Distance 和 Sleep Angle Deg 范围之内的车轮可以休眠:它会停止追踪,直到姿态改变。Sleep Distance 为负数时,车轮永远不会休眠。
- 专用服务器。 专用服务器不绘制轮胎,因此轮胎组件在那里保持空闲。
- 在 Content Browser 中选择 Add > Miscellaneous > Data Asset,选择类 CFTire Profile,并把资产命名为 DA_MyVehicle_TireProfile。默认值是个不错的起点:13 个弧向采样、3 行横向射线,最大凹陷为 14 厘米。
- 在车辆的适配器组件上,把 Tire Profile 设为新的配置文件,并勾选 Tires。Tire Profile 为空时,使用项目的默认轮胎配置文件
/Crushform/Presets/DA_CF_DefaultTireProfile。 - 为轮胎网格体指定一个使用
MF_CF_TireDeform的材质。最简单的做法是复制一份M_CF_TireDeform,并换上你自己的颜色。把它的RimRadius参数设为轮辋半径(网格单位),这样车轮才能在轮辋嵌入障碍物之前被推离。或者在配置文件中设置 Rim Radius Override(单位厘米)。 - 在 Project Settings > Plugins > Crushform Tire 中,检查 Budget 下的 Scope。默认为
Budgeted。如果轮胎追踪需要忽略某些对象通道,请在 Tracing 下添加它们。其余 Budget 值和 Sleep 阈值也在这里;见 项目设置。
蓝图通过适配器的 Get Tires 获取器访问轮胎组件。该组件本身没有蓝图函数,因此下方的蓝图通过这个获取器工作。当自定义事件 CheckTyres 触发时,它检查车辆是否有轮胎组件,并打印结果。这是在调校脚本接触轮胎之前的一个快速检查。轮胎本身的蓝图工作由适配器自己的事件完成:Build Tire Wheels 列出车轮,Build Load Ratios 给出每个车轮的负载。
在 C++ 中设置轮胎组件的配置文件。这些调用需要 CrushformVehicle 模块(适配器,CFVehicleAdapterComponent.h)和 CrushformTire 模块(CFTireComponent.h),请把两者加入模块 Build.cs 的 PublicDependencyModuleNames。在游戏开始后设置的配置文件,也会把该组件加入预算。
UCFTireComponent* Tires = Adapter->GetTires();Tires->SetProfile(MyTireProfile);能够乘坐车辆的 Pawn 实现 ICFTireViewer(位于 CrushformTire 模块的 CFTireViewer.h 中),并返回它所乘坐的车辆,这样预算就会让该车辆的轮胎保持形变。
AActor* GetCrushformTireViewedHost_Implementation() const override;| 属性 | 作用 | 默认值 |
|---|---|---|
UCFTireProfile::TraceChannel | 轮胎追踪地面所用的通道。 | ECC_WorldStatic |
UCFTireProfile::NumArcSamples | 横穿接触弧的射线数。 | 13 |
UCFTireProfile::NumLateralRows | 横穿胎面的射线行数。 | 3 |
UCFTireProfile::MaxDeflection | 最深凹陷,单位厘米。 | 14 |
UCFTireProfile::RestingDeflection | 静止轮胎被压扁的程度,以其半径的比例表示。 | 0.05 |
UCFTireProfile::LoadSensitivity | 负载对压扁程度的影响大小。 | 1 |
UCFTireProfile::MaxLoadFactor | 负载系数能达到的最大值。 | 2.5 |
UCFTireProfile::MergeAngleDeg | 距离相近的接触点只有在法线相差不超过此角度(度)时才合并为一个。取值过低时,大轮胎下的小圆形障碍物会占满四个接触点,地面就失去了自己的接触点。 | 45 |
UCFTireProfile::MinObstacleRadius | 圆形障碍物曲率所按的最小半径(厘米)。更细的障碍物(如管道)会按此半径的粗细来塑造凹陷。 | 3 |
UCFTireProfile::RimRadiusOverride | 轮辋半径(厘米)。0 时读取轮胎材质的 RimRadius 参数。 | 0 |
UCFTireProfile::RubberMargin | 车轮被推离障碍物后,障碍物与轮辋之间保留的橡胶厚度(厘米)。 | 2 |
UCFTireProfile::MaxPush | 整个车轮被推离障碍物的最大距离(厘米)。超过此值,轮辋可能会嵌入障碍物。 | 10 |
UCFTireSettings::Scope | 哪些轮胎形变:仅观察者的车辆组合、车辆组合加预算,还是所有轮胎。 | Budgeted |
UCFTireSettings::IgnoredObjectChannels | 地面追踪除轮胎自身通道外还要忽略的对象通道。 | 空 |
UCFTireSettings::DefaultProfile | 未指定配置文件的轮胎所用的配置文件。 | /Crushform/Presets/DA_CF_DefaultTireProfile |
UCFSettings::TireCustomDataOffset | 轮胎接触所用的第一个自定义基元数据索引。 | 0 |
UCFTireSettings::bEnabled | 开启时轮胎可以形变;关闭时每个轮胎都恢复为圆形。可由控制台变量 Crushform.Tire.Enable 覆盖。 | 开启 |
UCFTireSettings::MaxWheels | 同时允许形变的轮胎数量。可由控制台变量 Crushform.Tire.MaxWheels 覆盖。 | 30 |
UCFTireSettings::Radius | 其他轮胎可以形变的范围:距摄像机的距离,单位厘米。可由控制台变量 Crushform.Tire.Radius 覆盖。 | 4000 |
UCFTireSettings::LodDistance1 | 距摄像机的距离(厘米),超过它后轮胎使用更稀疏的射线扇形。可由控制台变量 Crushform.Tire.LodDistance1 覆盖。 | 1500 |
UCFTireSettings::LodDistance2 | 距摄像机的距离(厘米),超过它后轮胎使用最稀疏的扇形,并与简单碰撞进行检测。可由控制台变量 Crushform.Tire.LodDistance2 覆盖。 | 3000 |
UCFTireSettings::Hysteresis | 被授予的轮胎的各项边界会放宽多少,使处于边界上的轮胎不会闪烁。取值范围 0 到 0.9。可由控制台变量 Crushform.Tire.Hysteresis 覆盖。 | 0.15 |
UCFTireSettings::UpdateInterval | 两次预算处理之间的秒数。可由控制台变量 Crushform.Tire.UpdateInterval 覆盖。 | 0.25 |
UCFTireSettings::OnScreenTolerance | 车轮自上次被绘制起,仍被视为在屏幕内的秒数。可由控制台变量 Crushform.Tire.OnScreenTolerance 覆盖。 | 0.5 |
UCFTireSettings::SleepDistance | 轮胎可以休眠的范围:距静止姿态的距离,单位厘米。为负数时,轮胎永远不会休眠。 | 1 |
UCFTireSettings::SleepAngleDeg | 轮胎可以休眠的范围:相对静止姿态的角度,单位度。 | 0.5 |
验证是否生效
Section titled “验证是否生效”打开控制台,运行 Crushform.Tire.Debug 2。级别 1 会在屏幕上打印轮胎数量。级别 2 还会为每个轮胎绘制一个标签,显示其细节层级和授予状态,例如 T0 granted(层级 0 最精细),在轮毂处绘制一个绿点(车轮休眠时为蓝色),并在每个与地面的接触点绘制一个红点,沿接触法线绘制黄线。然后运行 Lvl_ProvingGround,让轿车驶过颠簸路面,并从斜坡上跳下。轮胎会在接触地面处鼓起,标签和点在此期间显示在轮胎上。调试面板中的 Tyres 行可以显示 Off、Counts 或 Rays,效果相同。除 Shipping 之外的所有构建中都可以使用它们。要看到包裹效果,请在你自己的关卡里把轮胎压到一个圆形障碍物上,例如横杆或原木:胎面会包裹住它,车轮则离开障碍物,使轮辋留在外面。
轮胎一直是圆的
Section titled “轮胎一直是圆的”原因。 没有配置文件的轮胎组件什么也不做。车辆的轮胎保持圆形,日志只在 Verbose 级别才会说明。在 Crushform Tire 中关闭 Enabled,或在控制台输入 Crushform.Tire.Enable 0,会让所有轮胎恢复为圆形。没有实现 ICFTireHost 的宿主会得到同样的结果,并记录一条警告:
%s: the host %s does not implement ICFTireHost, its tyres stay round修复。 在适配器上设置 Tire Profile,或在 Crushform Tire 中设置 Default Profile,并在 Crushform Tire 中打开 Enabled(控制台中的 Crushform.Tire.Enable 0 在本次会话中仍会覆盖它)。确认车辆是一个宿主:适配器本身就是宿主,而自定义 Actor 必须实现 ICFTireHost。
离摄像机较远的轮胎一直是圆的
Section titled “离摄像机较远的轮胎一直是圆的”原因。 Budgeted 只在 Radius 之内授予轮胎,并且全部轮胎最多只授予 Max Wheels 个。你自己的车辆始终会获得授予,但其他车辆要与剩下的名额共享。
修复。 在 Project Settings › Plugins › Crushform Tire 中提高 Radius 或 Max Wheels(Crushform.Tire.Radius 和 Crushform.Tire.MaxWheels 在本次会话中会覆盖它们),或者把 Scope 设为 Unlimited,让每个轮胎都获得完整细节。用 Crushform.Tire.Debug 1 检查预算。
轮辋嵌入障碍物
Section titled “轮辋嵌入障碍物”原因。 车轮没有被推离障碍物。这发生在:车轮没有轮辋半径,即轮胎材质的 RimRadius 和配置文件中的 Rim Radius Override 都没有设置;其宿主不接受推挤,例如覆盖了 Set Crushform Tire Wheel Offsets 的蓝图;或者障碍物比 Max Push 允许的更深。
修复。 在轮胎材质上设置 RimRadius,或在配置文件中设置 Rim Radius Override。在你自己的宿主上,请在 SetCrushformTireWheelOffsets 中应用 PushCm,并设置 bAcceptsPush;见 宿主接口。如果障碍物比车轮可被推开的距离更深,请提高 Max Push。
轮胎在专用服务器上不形变
Section titled “轮胎在专用服务器上不形变”原因。 专用服务器不绘制轮胎。组件保持空闲,并在 Verbose 级别记录这一点。
修复。 在客户端或监听服务器上测试轮胎。
轮胎接触没有被写入
Section titled “轮胎接触没有被写入”原因。 轮胎块占 32 个浮点数,从 Tire Custom Data Offset 开始,该值可取 0 到 4。它必须在车轮的污垢块(从 Wheel Custom Data Offset 开始,默认为 34)之前结束。该值大于 2 时,这一块会侵入污垢块,日志会记录一次:
%s: TireCustomDataOffset %d does not fit the primitive clear of WheelCustomDataOffset %d, tyre contacts are not written修复。 把 Tire Custom Data Offset 改回默认的 0,即使用索引 0 到 31。该值改变时,编辑器会重建依赖它的材质函数。

