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

参考ACTOR

ACFBreakableTree

模块CrushformBreakable头文件CFBreakableTree.h父类AActor

树干在整个生命周期内只有一个物理刚体:直立、弯曲、倒下,或弯曲后被锁定,最终冻结为静态几何体。

直立状态是一个没有关节的运动学刚体,从 BeginPlay 起处于休眠状态——关卡中放置的森林在 UCFPropContactComponent 将其激活之前不耗费任何性能。屈服由角度决定:权威端越过 YieldAngleDegrees 时即确认屈服;客户端则在本地预测同一次越过,并以零延迟开始倒下——淡出驱动弹簧只是一次普通且可逆的关节修改,不同于断开关节或迁移塑性驱动目标。只有当权威端的 bYielded 确实确认了该预测时,客户端才会释放关节(即 FellAndFall 的硬性结束);未被确认的预测会回滚。

树木也可以由受 Dynamic Wind 驱动的蒙皮网格体绘制(TrunkSkinnedMesh)。它纯粹是视觉效果,依附于同一个树干刚体:当它在构造或 BeginPlay 时拥有网格体,TrunkMesh 会被隐藏,仅作为物理刚体和碰撞代理保留,因此上述所有规则仍只作用于 TrunkMesh。

函数

AUTHORITY · 服务器,每个端LOCAL · 本机PURE · 只读
UStaticMeshComponent* GetTrunkMesh() const
PUREC++ ONLY

树干的物理刚体与碰撞代理。当 TrunkSkinnedMesh 绘制树木时隐藏。

UInstancedSkinnedMeshComponent* GetTrunkSkinnedMesh() const
PUREC++ ONLY

可选的蒙皮网格体,用于代替 TrunkMesh 绘制树木。可以不指定网格体。

UCFTreeConfig* GetTreeConfig() const
PUREC++ ONLY

每个树种的调节资产。未指定时为空。

UPhysicsConstraintComponent* GetTrunkConstraint() const
PUREC++ ONLY

在树木处于激活状态期间,将树干固定在世界中的关节。

bool IsArmed() const
LOCAL

附近车辆是否已激活该树木(其关节存在且处于物理模拟状态)。仅限本机:激活状态不复制。

分类
Crushform|Tree
bool IsYielded() const
PURE

树木是否已屈服:被伐倒的树干已开始倒下,或弯曲的立柱已到达其止点。由权威端复制。

分类
Crushform|Tree
bool IsSettled() const
PURE

树干是否已冻结为静态几何体。由权威端复制。

分类
Crushform|Tree
int32 GetRespawnCount() const
PURE

至今的重生次数,达到 256 后回绕。使用计数器而非标志位,因此第二次重生仍是客户端能够看到的变化。

分类
Crushform|Tree
bool RespawnNowOnAuthority()
AUTHORITYC++ ONLY

仅限权威端。立即重新站立一棵已屈服的树(倒下、正在伐倒或被锁定的立柱),走计时器的路径,无论重生条件如何。对于直立的树,或在非权威端上调用时,返回 false。

bool IsStateChangeFresh() const
PUREC++ ONLY

最近一次复制的状态变化(屈服或停稳)是否足够新,能够被实时看到。权威端上始终为 true。

float GetDeflectionDegrees() const
PURE

当前弯曲角度(度),由树干自身的实时旋转测得——绝非单独追踪的值。

分类
Crushform|Tree
void Arm()
LOCALC++ ONLY

仅限本机。创建关节并开始模拟物理——若已激活,则仅取消任何待处理的 RequestDisarm()。具有幂等性,开销也足够低,可以对车辆附近的每棵树每 tick 调用一次。若缺少 TreeConfig 或其未通过 UCFTreeConfig::ValidateTreeConfig,则拒绝激活(仅记录一次日志);若树木不在游戏中(BeginPlay 之前,或其所在的单元格被流式卸载后 EndPlay 之后),则静默拒绝。

void RequestDisarm()
LOCALC++ ONLY

仅限本机。在 DisarmDelaySeconds 之后安排 Disarm(),除非期间有 Arm() 重新调用。已屈服后不做任何处理——正在倒下或被锁定的树干永远不会重新变回运动学刚体——在不处于游戏中的状态下同样如此,与 Arm() 一致。

void UpdateBendVisual()
C++ ONLY

将关节的当前偏移写入每个树干网格体的 Custom Primitive Data,供 WPO 弯曲材质使用(参见 BendAmountCpdIndex 等)。未激活时为廉价的空操作。

float ComputeArmRadiusCm(float SpeedCmS, float DeltaSeconds)
C++ ONLY

车辆激活其周围树木的半径,单位为 cm:取 ArmMinRadiusCm,或车身在 DeltaSeconds(钳制在 0.1-0.35 s)内移动的距离以 3x 余量计,两者取较大者。激活必须先于碰撞发生,因为未激活的树木是一堵运动学墙。

属性

TObjectPtr<UStaticMeshComponent> TrunkMesh

树干的物理刚体与碰撞代理。

分类
Crushform|Tree
TObjectPtr<UInstancedSkinnedMeshComponent> TrunkSkinnedMesh
分类
Crushform|Tree
TObjectPtr<UPhysicsConstraintComponent> TrunkConstraint

在树木处于激活状态期间,将树干固定在世界中的关节。

分类
Crushform|Tree
TObjectPtr<UCFTreeConfig> TreeConfig
分类
Crushform|Tree
bool bYielded = false

树木屈服时(被伐倒的树干开始倒下,或弯曲的立柱到达其止点),由权威端设置;已复制。

默认值
false
分类
Crushform|Tree
bool bSettled = false

树干冻结为静态几何体时,由权威端设置;已复制。

默认值
false
分类
Crushform|Tree

事件

FCFOnTreeHitDynamicDelegate OnHit
(ACFBreakableTree* Tree, AActor* OtherActor, FVector Location, float DeltaVCmS)

每个事件都会在每一端上触发,依据该端自身所见的内容,且不会传递给之后加入的玩家。

分类
Crushform|Tree
FCFOnTreeHitDelegate OnHitNative
C++ ONLY
(ACFBreakableTree&, AActor*, const FVector&, float)

OnHit 的原生对应委托。

FCFOnTreeYieldedDynamicDelegate OnYielded
(ACFBreakableTree* Tree, bool bPredicted)
分类
Crushform|Tree
FCFOnTreeYieldedDelegate OnYieldedNative
C++ ONLY
(ACFBreakableTree&, bool)

OnYielded 的原生对应委托。

FCFOnTreeEventDynamicDelegate OnLanded
(ACFBreakableTree* Tree)
分类
Crushform|Tree
FCFOnTreeEventDelegate OnLandedNative
C++ ONLY
(ACFBreakableTree&)

OnLanded 的原生对应委托。

FCFOnTreeEventDynamicDelegate OnSettled
(ACFBreakableTree* Tree)
分类
Crushform|Tree
FCFOnTreeEventDelegate OnSettledNative
C++ ONLY
(ACFBreakableTree&)

OnSettled 的原生对应委托。

FCFOnTreeEventDynamicDelegate OnRespawned
(ACFBreakableTree* Tree)
分类
Crushform|Tree
FCFOnTreeEventDelegate OnRespawnedNative
C++ ONLY
(ACFBreakableTree&)

OnRespawned 的原生对应委托。

FCFOnTreeEventDynamicDelegate OnYieldRolledBack
(ACFBreakableTree* Tree)
分类
Crushform|Tree
FCFOnTreeEventDelegate OnYieldRolledBackNative
C++ ONLY
(ACFBreakableTree&)

OnYieldRolledBack 的原生对应委托。