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

世界可破坏的树木与电线杆

可破坏的树木与电线杆

可破坏的树是一根车辆能够撞倒的树干。车辆撞上树时,树会弯曲。当它被推过屈服角度后,要么倒下并停在落地的位置,要么(对于电线杆)弯曲并保持倾斜。过一段时间,它会重新立起。

轿车撞倒了一棵树:树干弯下去并倒下。
电线杆在轿车撞击下弯曲,并保持倾斜。

可破坏的树是一个 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 度)处停下,并保持其倾斜。电线杆属于这一类。
  • 落地。 被松开的树干以 LandMinDeltaVCmS(80 cm/s)或更大的速度撞上地面,即视为落地。
  • 停稳。 树干会在躺下的位置冻结为静态几何体。
  • 重生。 RespawnDelaySeconds(默认 300 秒)之后,树会重新立起,并在 RespawnSinkSeconds(3 秒)内下沉到位。在满足以下条件之前,它会等待:没有玩家位于 RespawnClearRadiusCm(4000 cm)之内,RespawnBlockingObjectTypes 中的刚体不占据它的位置,并且在 bRespawnOnlyWhenUnseen 开启时,没有摄像机正在看它。

倒下的树干会阻挡车辆 VehiclePassThroughDelaySeconds(1 秒),之后车辆便可以穿过它,除非 bFallenTrunkCollidesWithVehicles 开启。树的击中、屈服、落地、停稳和重生事件会在每个端上根据各自所见的情况触发。中途加入的玩家不会收到加入之前已经发生的事件。

Crushform
Tree
Trunk MeshTrunkMesh
Trunk Skinned MeshTrunkSkinnedMesh
Trunk ConstraintTrunkConstraint
Tree ConfigDA_CF_Tree
已放置的树的 Crushform Tree 分组,其 Tree Config 设为 DA_CF_Tree。

树的 Tree Config 数据资产保存树种。没有配置,或配置未通过检查的树,会拒绝激活。

本节使用 Proving Ground 上随附的树。要制作自己的树种,请参见第 3 步。

  1. 在 Content Browser 中,随附的树位于 Plugins › Crushform Content › Trees。
  2. 把 BP_CF_Tree(倒下型的树,Fell and Fall)或 BP_CF_Pole(弯曲锁定型的电线杆,Bend and Lock)拖入关卡。两者都是已放置的 Actor,其 Tree Config 分别设为它们树种的数据资产 DA_CF_Tree 或 DA_CF_Pole。
  3. 要制作自己的树种,请在 Content Browser 中选择 Add › Miscellaneous › Data Asset,选择类 CFTree Config,并为它命名。按照下面主要设置表中的说明,设置 Mass Kg、Yield Mode 和各个角度。
Crushform
Tree
Mass Kg900.0
Yield ModeFell And Fall
Yield
Yield Angle Degrees15.0
Felling
Felling Drive Fade Seconds0.01
Felling Damping Strength50000000.0
Release Angle Degrees65.0
Vehicle Pass Through Delay Seconds1.0
Stop Angle Degrees45.0
Bend and Lock Lock Strength Multiplier100.0
DA_CF_Tree 的 Tree 分组,其中 Yield 和 Felling 分组已展开。
  1. 在关卡中选中该树。在 Details 面板中,于 Crushform › Tree 下,把 Tree Config 设为你的数据资产。
  2. 确保应当撞倒这棵树的车辆,其适配器上的 Breaks Props 已开启(默认即为开启)。适配器随后会创建 CF_PropContact 组件。

在你自己的项目中,蓝图可以对树做出反应。该蓝图在树开始播放时,将一个处理函数绑定到 On Yielded。每当树屈服时,处理函数打印一条消息。

该蓝图在树开始播放时,将一个处理函数绑定到 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::YieldModeFellAndFall 会让树干倒下;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 分组中。

在除 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。如果出现第二行,其文字会指出有问题的数值。请在数据资产中修正它,然后重新运行关卡。

原因。 车辆没有 CF_PropContact 组件,因为它的适配器上 Breaks Props 是关闭的。没有任何东西激活这棵树,因此它保持为一面运动学墙,挡住车辆。接触组件只有在其刚体醒着或速度快于 TreeArmMinSpeedCmS(默认为 5 cm/s)时,才会激活树。

修复。 在车辆的适配器上开启 Breaks Props。适配器随后会创建 CF_PropContact,由它激活车辆靠近的树。

倒下的树干挡住车辆,或者树从不重生

Section titled “倒下的树干挡住车辆,或者树从不重生”

原因。 在 bFallenTrunkCollidesWithVehicles 开启时,倒下的树干会阻挡车辆;在 Fell and Fall 屈服之后的 VehiclePassThroughDelaySeconds 内,它同样会阻挡车辆。RespawnDelaySeconds 为 0 的树永不重生。树只有在没有玩家位于其清空半径之内、没有属于其阻挡类型的对象占据其位置,并且(在 bRespawnOnlyWhenUnseen 开启时)没有摄像机看着它的情况下,才会重生。

修复。 把 bFallenTrunkCollidesWithVehicles 关闭,让穿行延迟过后,车辆可以穿过树干。要让它重生,请把 RespawnDelaySeconds 设为大于零的值,并把玩家或阻挡对象移离树的位置。

原因。 UCFTreeConfig::DrivePositionStrength 太硬。配置中的注释说明,驱动过强会让树干变成任何车辆都推不动的刚性墙。DriveVelocityStrength 应当保持在 DrivePositionStrength 的十分之一左右。

修复。 降低 DrivePositionStrength,并让 DriveVelocityStrength 保持在它的十分之一左右。然后在关卡中推动这棵树,检查它是否能独立站立。

其他世界系统请参见围栏与道具和撞击反馈。