世界可破坏的树木与电线杆
可破坏的树木与电线杆
可破坏的树是一根车辆能够撞倒的树干。车辆撞上树时,树会弯曲。当它被推过屈服角度后,要么倒下并停在落地的位置,要么(对于电线杆)弯曲并保持倾斜。过一段时间,它会重新立起。
可破坏的树是一个 ACFBreakableTree Actor。它有一个物理刚体,即树干,以及一个把树干固定在地面上的关节。关节以驱动弹簧托住树干,对于电线杆还有一个硬限位。在车辆靠近之前,树干处于休眠状态,不占用任何资源:关卡中即使有大量树木,车辆远离时开销也很低。
- 激活。 带有
CF_PropContact组件的车辆会激活它周围的树。树干开始模拟,关节随之创建。处于休眠且速度慢于UCFPropContactComponent::TreeArmMinSpeedCmS(默认为 5 cm/s)的刚体不会激活任何树,因此它附近的树保持静止。未激活的树是一面运动学墙,仍然会挡住车辆。 - 屈服。 树干倾斜超过
UCFTreeConfig::YieldAngleDegrees(15 度)时,树便屈服。接下来发生什么,取决于树种的 Yield Mode:- Fell and Fall(
FellAndFall):关节在ReleaseAngleDegrees(65 度)处松开,树干自由倒下。 - Bend and Lock(
BendAndLock):树干在StopAngleDegrees(45 度)处停下,并保持其倾斜。电线杆属于这一类。
- Fell and Fall(
- 落地。 被松开的树干以
LandMinDeltaVCmS(80 cm/s)或更大的速度撞上地面,即视为落地。 - 停稳。 树干会在躺下的位置冻结为静态几何体。
- 重生。
RespawnDelaySeconds(默认 300 秒)之后,树会重新立起,并在RespawnSinkSeconds(3 秒)内下沉到位。在满足以下条件之前,它会等待:没有玩家位于RespawnClearRadiusCm(4000 cm)之内,RespawnBlockingObjectTypes中的刚体不占据它的位置,并且在bRespawnOnlyWhenUnseen开启时,没有摄像机正在看它。
倒下的树干会阻挡车辆 VehiclePassThroughDelaySeconds(1 秒),之后车辆便可以穿过它,除非 bFallenTrunkCollidesWithVehicles 开启。树的击中、屈服、落地、停稳和重生事件会在每个端上根据各自所见的情况触发。中途加入的玩家不会收到加入之前已经发生的事件。
| Crushform | ||
|---|---|---|
| Tree | ||
| Trunk Mesh | TrunkMesh | |
| Trunk Skinned Mesh | TrunkSkinnedMesh | |
| Trunk Constraint | TrunkConstraint | |
| Tree Config | DA_CF_Tree | |
树的 Tree Config 数据资产保存树种。没有配置,或配置未通过检查的树,会拒绝激活。
本节使用 Proving Ground 上随附的树。要制作自己的树种,请参见第 3 步。
- 在 Content Browser 中,随附的树位于 Plugins › Crushform Content › Trees。
- 把
BP_CF_Tree(倒下型的树,Fell and Fall)或BP_CF_Pole(弯曲锁定型的电线杆,Bend and Lock)拖入关卡。两者都是已放置的 Actor,其 Tree Config 分别设为它们树种的数据资产DA_CF_Tree或DA_CF_Pole。 - 要制作自己的树种,请在 Content Browser 中选择 Add › Miscellaneous › Data Asset,选择类 CFTree Config,并为它命名。按照下面主要设置表中的说明,设置 Mass Kg、Yield Mode 和各个角度。
| Crushform | ||
|---|---|---|
| Tree | ||
| Mass Kg | 900.0 | |
| Yield Mode | ||
| Yield | ||
| Yield Angle Degrees | 15.0 | |
| Felling | ||
| Felling Drive Fade Seconds | 0.01 | |
| Felling Damping Strength | 50000000.0 | |
| Release Angle Degrees | 65.0 | |
| Vehicle Pass Through Delay Seconds | 1.0 | |
| Stop Angle Degrees | 45.0 | |
| Bend and Lock Lock Strength Multiplier | 100.0 | |
- 在关卡中选中该树。在 Details 面板中,于 Crushform › Tree 下,把 Tree Config 设为你的数据资产。
- 确保应当撞倒这棵树的车辆,其适配器上的 Breaks Props 已开启(默认即为开启)。适配器随后会创建
CF_PropContact组件。
在你自己的项目中,蓝图可以对树做出反应。该蓝图在树开始播放时,将一个处理函数绑定到 On Yielded。每当树屈服时,处理函数打印一条消息。
在 C++ 中,同样的事情使用原生委托完成。每个事件都有一个 ...Native 对应项,C++ 监听器可以添加到其上:
#include "CFBreakableTree.h"
void ListenToTree(ACFBreakableTree* Tree){ if (IsValid(Tree)) { Tree->OnYieldedNative.AddLambda([](ACFBreakableTree& Yielded, bool bPredicted) { UE_LOG(LogTemp, Log, TEXT("%s yielded, predicted: %d"), *Yielded.GetName(), bPredicted); }); }}这段 C++ 代码需要在你的 Build.cs 中加入 CrushformBreakable 模块。模块列表见安装。头文件中声明了 FCFOnTreeYieldedDelegate OnYieldedNative,参数为 ACFBreakableTree& Tree, bool bPredicted。状态查询包括 IsArmed()、IsYielded()、IsSettled()、GetRespawnCount() 和 GetDeflectionDegrees(),它们都是 const 的。
树种的设置位于 UCFTreeConfig 上。在它的 Details 面板中,这些设置位于 Crushform › Tree 下的子分组中:Yield、Felling、Drive、Vehicles、Events、Feedback 和 Respawn。默认值来自插件本身,因此新建的配置已经带有它们。
| 属性 | 作用 | 默认值 |
|---|---|---|
UCFTreeConfig::MassKg | 树干的质量。它是车辆推动它时手感的主要因素。 | 900 |
UCFTreeConfig::YieldMode | FellAndFall 会让树干倒下;BendAndLock 会让它在停止角度处停下,并保持倾斜。 | FellAndFall |
UCFTreeConfig::YieldAngleDegrees | 树屈服所需的倾斜角度,单位为度。 | 15 |
UCFTreeConfig::ReleaseAngleDegrees | 仅限 Fell and Fall:关节松开时的倾斜角度。 | 65 |
UCFTreeConfig::StopAngleDegrees | 仅限 Bend and Lock:电线杆弯到的停止角度。 | 45 |
UCFTreeConfig::DrivePositionStrength | 在其锥形范围内把树干保持直立的弹簧。不能为零。 | 5.0e8 |
UCFTreeConfig::bFallenTrunkCollidesWithVehicles | 倒下的树干是否继续阻挡车辆。关闭时,车辆会在穿行延迟之后穿过它。 | false |
UCFTreeConfig::VehiclePassThroughDelaySeconds | 仅限 Fell and Fall:正在倒下的树干仍然阻挡车辆的时长。 | 1 |
UCFTreeConfig::HitMinDeltaVCmS | 被计为击中的最小速度变化量,单位 cm/s。 | 30 |
UCFTreeConfig::RespawnDelaySeconds | 被撞倒或弯曲的树保持倒下的时长。0 表示永不重生。 | 300 |
UCFTreeConfig::RespawnClearRadiusCm | 玩家距离在此范围内时不重生,单位厘米。 | 4000 |
UCFTreeConfig::RespawnBlockingObjectTypes | 位于树的位置上、属于这些对象类型的刚体会让它保持倒下。 | ECC_Vehicle、ECC_Pawn、ECC_PhysicsBody |
UCFTreeConfig::bRespawnOnlyWhenUnseen | 玩家的摄像机正在看这棵树时不重生。 | true |
UCFTreeConfig::HitFeedbackTag | 击中时播放的撞击标签。留空则播放插件的 Crushform.Impact.Tree.Hit。 | 空 |
UCFTreeConfig::YieldFeedbackTag | 屈服时的撞击标签。留空则播放插件的 Crushform.Impact.Tree.Break 或 Crushform.Impact.Tree.Bend。 | 空 |
UCFTreeConfig::LandFeedbackTag | 落地时的撞击标签。留空则播放插件的 Crushform.Impact.Tree.Land。 | 空 |
UCFBreakableSettings::TreeCollisionProfile | 树干的碰撞配置文件。车辆必须能够阻挡它。 | None(使用 Destructible) |
UCFBreakableSettings::TreeWheelTraceChannel | 车辆车轮追踪地面所用的通道。 | ECC_WorldDynamic |
UCFBreakableSettings::RespawnCheckIntervalSeconds | 已屈服的树检查是否可以重生的频率,单位秒。 | 5 |
项目设置位于 Project Settings › Plugins › Crushform Breakable 下的 Trees 和 Respawn 分组中。
验证是否生效
Section titled “验证是否生效”在除 Shipping 之外的任何构建中,用波浪号键打开控制台。
stat CrushformBreakable会显示 Breakable Tree Tick 和 Breakable Tree Trunk Hit 的周期。车辆靠近树时,它们会有变化。- 让车辆撞上
BP_CF_Tree:树干弯曲,越过屈服角度后倒下。撞上BP_CF_Pole:它弯曲并保持倾斜。 - 要快速验证重生,可以把你的配置中的
RespawnDelaySeconds设为几秒。当没有玩家位于它的清空半径内,且没有摄像机看到它时,树会重新立起。
如果车辆撞上时树仍然立着,请参见下方故障排除的第一条。
原因。 树没有 Tree Config,或者它的配置未通过检查。这时树会拒绝激活,并且只记录一行日志,只记录一次:
Tree %s has no TreeConfig assigned, refusing to arm或者,对于未通过 UCFTreeConfig::ValidateTreeConfig 的配置:
Tree %s has an invalid TreeConfig (%s), refusing to arm修复。 在关卡中为树设置 Tree Config。如果出现第二行,其文字会指出有问题的数值。请在数据资产中修正它,然后重新运行关卡。
车辆停在树前,树却从不弯曲
Section titled “车辆停在树前,树却从不弯曲”原因。 车辆没有 CF_PropContact 组件,因为它的适配器上 Breaks Props 是关闭的。没有任何东西激活这棵树,因此它保持为一面运动学墙,挡住车辆。接触组件只有在其刚体醒着或速度快于 TreeArmMinSpeedCmS(默认为 5 cm/s)时,才会激活树。
修复。 在车辆的适配器上开启 Breaks Props。适配器随后会创建 CF_PropContact,由它激活车辆靠近的树。
倒下的树干挡住车辆,或者树从不重生
Section titled “倒下的树干挡住车辆,或者树从不重生”原因。 在 bFallenTrunkCollidesWithVehicles 开启时,倒下的树干会阻挡车辆;在 Fell and Fall 屈服之后的 VehiclePassThroughDelaySeconds 内,它同样会阻挡车辆。RespawnDelaySeconds 为 0 的树永不重生。树只有在没有玩家位于其清空半径之内、没有属于其阻挡类型的对象占据其位置,并且(在 bRespawnOnlyWhenUnseen 开启时)没有摄像机看着它的情况下,才会重生。
修复。 把 bFallenTrunkCollidesWithVehicles 关闭,让穿行延迟过后,车辆可以穿过树干。要让它重生,请把 RespawnDelaySeconds 设为大于零的值,并把玩家或阻挡对象移离树的位置。
树干像一堵墙
Section titled “树干像一堵墙”原因。 UCFTreeConfig::DrivePositionStrength 太硬。配置中的注释说明,驱动过强会让树干变成任何车辆都推不动的刚性墙。DriveVelocityStrength 应当保持在 DrivePositionStrength 的十分之一左右。
修复。 降低 DrivePositionStrength,并让 DriveVelocityStrength 保持在它的十分之一左右。然后在关卡中推动这棵树,检查它是否能独立站立。