跳转到内容
CRUSHFORMV1.1.0
在 Fab 上获取

表面轮胎形变

轮胎形变

受载的轮胎不会保持圆形。在与地面接触处,它向两侧鼓起,在接触点凹陷,车辆压得越重,轮胎被压扁得越厉害。插件把这种效果绘制在车辆的车轮网格体上,因此轮胎无论在哪种地面上都显得承受着负载。压在圆形障碍物(例如横杆、原木或路缘石的圆角边缘)上的轮胎会包裹住它,车轮则会离开障碍物,使轮辋留在外面。本页介绍决定这种效果的配置文件、决定哪些轮胎会发生形变的预算,以及如何设置两者。

轿车后轮在路面上的低角度侧视图,两侧向外鼓起,与地面接触处被压扁。
轿车后轮:两侧鼓起,接触处被压扁。

车辆的每个车轮,只要预算允许,都会获得一个轮胎形变器。形变器追踪轮胎下方的地面,并把接触信息写入车轮网格体,轮胎材质则根据这些接触绘制鼓起效果。预算未授予的轮胎不会获得形变器,也不会鼓起。你自己车辆的轮胎始终会形变;其他车辆的轮胎则在靠近摄像机并处于预算上限之内时形变。

  • 接触。 轮胎用一组扇形射线追踪地面。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 为负数时,车轮永远不会休眠。
  • 专用服务器。 专用服务器不绘制轮胎,因此轮胎组件在那里保持空闲。
  1. 在 Content Browser 中选择 Add > Miscellaneous > Data Asset,选择类 CFTire Profile,并把资产命名为 DA_MyVehicle_TireProfile。默认值是个不错的起点:13 个弧向采样、3 行横向射线,最大凹陷为 14 厘米。
  2. 在车辆的适配器组件上,把 Tire Profile 设为新的配置文件,并勾选 Tires。Tire Profile 为空时,使用项目的默认轮胎配置文件 /Crushform/Presets/DA_CF_DefaultTireProfile。
  3. 为轮胎网格体指定一个使用 MF_CF_TireDeform 的材质。最简单的做法是复制一份 M_CF_TireDeform,并换上你自己的颜色。把它的 RimRadius 参数设为轮辋半径(网格单位),这样车轮才能在轮辋嵌入障碍物之前被推离。或者在配置文件中设置 Rim Radius Override(单位厘米)。
  4. 在 Project Settings > Plugins > Crushform Tire 中,检查 Budget 下的 Scope。默认为 Budgeted。如果轮胎追踪需要忽略某些对象通道,请在 Tracing 下添加它们。其余 Budget 值和 Sleep 阈值也在这里;见 项目设置。

蓝图通过适配器的 Get Tires 获取器访问轮胎组件。该组件本身没有蓝图函数,因此下方的蓝图通过这个获取器工作。当自定义事件 CheckTyres 触发时,它检查车辆是否有轮胎组件,并打印结果。这是在调校脚本接触轮胎之前的一个快速检查。轮胎本身的蓝图工作由适配器自己的事件完成:Build Tire Wheels 列出车轮,Build Load Ratios 给出每个车轮的负载。

当自定义事件 CheckTyres 触发时,蓝图检查车辆是否有轮胎组件,并打印结果。

在 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

打开控制台,运行 Crushform.Tire.Debug 2。级别 1 会在屏幕上打印轮胎数量。级别 2 还会为每个轮胎绘制一个标签,显示其细节层级和授予状态,例如 T0 granted(层级 0 最精细),在轮毂处绘制一个绿点(车轮休眠时为蓝色),并在每个与地面的接触点绘制一个红点,沿接触法线绘制黄线。然后运行 Lvl_ProvingGround,让轿车驶过颠簸路面,并从斜坡上跳下。轮胎会在接触地面处鼓起,标签和点在此期间显示在轮胎上。调试面板中的 Tyres 行可以显示 Off、Counts 或 Rays,效果相同。除 Shipping 之外的所有构建中都可以使用它们。要看到包裹效果,请在你自己的关卡里把轮胎压到一个圆形障碍物上,例如横杆或原木:胎面会包裹住它,车轮则离开障碍物,使轮辋留在外面。

轿车后轮的轮胎调试绘制:每个轮胎上有一个绿色标签,显示 T0 granted,轮毂处为绿点,与地面的接触处为红点,并带有黄线。
Crushform.Tire.Debug 2:每个轮胎的细节层级和授予状态、它的轮毂,以及与地面的接触点。
从正面看轿车:轮胎在车重下被压扁。

原因。 没有配置文件的轮胎组件什么也不做。车辆的轮胎保持圆形,日志只在 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 检查预算。

原因。 车轮没有被推离障碍物。这发生在:车轮没有轮辋半径,即轮胎材质的 RimRadius 和配置文件中的 Rim Radius Override 都没有设置;其宿主不接受推挤,例如覆盖了 Set Crushform Tire Wheel Offsets 的蓝图;或者障碍物比 Max Push 允许的更深。

修复。 在轮胎材质上设置 RimRadius,或在配置文件中设置 Rim Radius Override。在你自己的宿主上,请在 SetCrushformTireWheelOffsets 中应用 PushCm,并设置 bAcceptsPush;见 宿主接口。如果障碍物比车轮可被推开的距离更深,请提高 Max Push。

原因。 专用服务器不绘制轮胎。组件保持空闲,并在 Verbose 级别记录这一点。

修复。 在客户端或监听服务器上测试轮胎。

原因。 轮胎块占 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。该值改变时,编辑器会重建依赖它的材质函数。