Contents

Chaos使用文档

在这里我们将跳过如何开启、编译、下载的基本步骤。并且虽然Chaos是一整套的物理引擎,本文则不对其与Phx的通用功能做出特殊说明而只针对其本身的破碎系统

资源与编辑器

https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105142853.png

GeometryCollection

我们进行破碎的第一步就是将Mesh转化为Chaos可识别的GeometryCollection资源,GeometryCollection是Chaos的物理资源。

Mesh要求

生成GeometryCollection并不是所有的Mesh都符合要求,并且为了达到更高的效率,我们依旧需要Mesh制作中符合某些特定的标准才可以。

  1. 模型需要封闭(Watertight),无交叉(Non-Intersecting)。
  2. 对于凸物体来说其分割将会更加的灵活能施加更多的控制,所以对于复炸的模型我们需要将他的Mesh拆分开,分别配置其破碎,最后通过蓝图将这些东西聚集成整体。
  3. 我们的轴向选择需要符合Unreal的Gridding Ststem的要求,这样我们控制Width和Height的时候才能更加的高效。
  4. 要考虑的另一个概念是 材质 指定,即使模块的材质相同,也应每个材质类型应用唯一的材质ID。这样在碎裂时可生成第二个材质ID,然后即可指定适当的内部材质。 在下方视频中,几何体集由两个网格体组成,而这两个网格体共享相同纹理,但使用两个不同的材质类型。因此,石料和混凝土的内面均可使用唯一材质;如果一种材质已被使用,则可将一个材质ID指定到内面。
  5. 将多个不同的Mesh整合在一个GeometryCollection中,将会使得如果有相同材质的话会共享材质并且降低DC。
  6. 多个Mesh是可以结合成为一个GeometryCollection,虽然小的物体在空间中的拜访非常灵活,但是会造成高的DrawCall,可见的接缝,并且十字交叉的重复。大型的Mesh会导致灵活性降低,但是会隐藏接缝。

创建GeometryCollection

https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105143103.png

我们使用的所有的Chaos的破碎都需要存储在Geometry Collection的资源内。 https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210104111204.png

Collision Settings,

  1. Collision Type:我们的Collision Type一共有两种,一种是Implicit-Implicit一种是Particle-Implicit。他是和Implicit Type有着密不可分的关系。使用Level Set Volumes时,应将 Collision Type设为Particle-Implicit。也可将其设为 隐式-隐式(Implicit-Implicit),但其在后台仍会检查隐式表面的碰撞粒子。
  2. Implicit type:总共有四种,盒体、球体或胶囊体和Level Set Volumes。盒体以类似于边界框的形式包裹形体,而球体和胶囊体则放置在刚体内部来适应空间。 在模拟期间,这能加快计算速度并降低内存占用率,但会降低精度。Level Set Volumes,此类体积使用体素化网格对刚体采样,并生成几何体的有向距离场。Level Set Volumes精度更高,可调整的性能,不过内存使用更高 https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210104151527.png
    1. Min Level Set Resolution
    2. Max Level Set Resolution
    3. MinCluster Level Set Resolution
    4. MaxCluster Level Set Resolution
  3. Collision object Reduction percentage:如Box之类的碰撞,其类似于外包围盒的那种类型,一般来说包围盒都会比破碎物体本身要打,所以我们在模拟一开始包围盒之间就会交叉,调整整个参数将会降低。

破碎系统

我们将在这里来选择我们的破碎系统 https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105115731.png

https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105143205.png

碎裂方法有多种不同类型,结合不同技巧便能产生更为有趣的破坏效果。可尝试使用不同选项和设置来实现理想效果。

使用Shift-B 可以看到Bone Color,当你选择了一个GeometryCollection. 使用Shift-Q 和Shift-E可以看分割后的场景 使用Shift-S 和Shift-W切换Levels https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105120142.png

破碎层级 分簇

我们可以将破碎划分层级。一组相邻的碎片将会组成一个Cluster,每个Cluster也可以组成一个新的Custer。

https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105142113.png

  1. 在CusterUI中,我们使用Flatten,可以抹平所有的层级
  2. 使用Auto,我们可以自动设置层级。
  3. 在GeometryCollection上可以设置不同的Level对应的Threshold,只有到达相应的Threshold,才会继续向下破碎。

簇组索引

设置各Actor上的 簇组索引 属性为另一种可用于控制一组几何体集分簇的工具。 https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105143349.png

GamePlay

破碎事件

对于Chaos的破碎块来说,我们有两个不同的Notify,一个是Break,一个是Collision。break只的是在物体进行破碎的时候调用,而Collision与一般的Collision一样是对于每一个破碎快发生Collision的时候调用

OnChaosBreakEvent

https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105144432.png

  1. OnChaosBreakEvent,当我们增加力场,物理开始破坏时,我们将拿到这个事件。值得注意的是,这个事件的调用次数是跟破碎的块数一致的,如果我们破碎了1000个块,如果它会发出事件的话,会调用1000次。
  2. 只有GeometryCollection会产生OnChaosBreakEvent,我们可以控制它是否发送事件,通过SetNotifyBreaks.
  3. 每个OnChaosBreakEvent拥有自己的参数。我们可以根据参数来进行debug或者其他操作
    1. UPrimitiveComponent* Component;
    2. FVector Location;
    3. FVector Velocity;
    4. FVector AngularVelocity;
    5. float Mass;

OnChaosPhysicsCollision

https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105144446.png

同样的,我们的Collision也是每块都有自己的碰撞事件,其数据结构为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
USTRUCT(BlueprintType)
struct CHAOSSOLVERENGINE_API FChaosPhysicsCollisionInfo
{
	GENERATED_BODY()
public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Chaos")
	UPrimitiveComponent* Component;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Chaos")
	UPrimitiveComponent* OtherComponent;

	/** Location of the impact */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Chaos")
	FVector Location;
	
	/** Normal at the impact */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Chaos")
	FVector Normal;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Chaos")
	FVector AccumulatedImpulse;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Chaos")
	FVector Velocity;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Chaos")
	FVector OtherVelocity;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Chaos")
	FVector AngularVelocity;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Chaos")
	FVector OtherAngularVelocity;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Chaos")
	float Mass;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Chaos")
	float OtherMass;
};

FieldSystem

我们实现所有的破碎效果都需要使用Chaos的FieldSystem。 https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105143421.png Field使用一个空间的区域去控制物理模拟的属性。

FieldSystemComponent

使用力场来进行物理世界的模拟操作。力场的使用非常精确的控制在某一个区域中,这使得我们可以在空间中进行非常细致的控制。 https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210104140800.png

同时存在多个Field System是非常普遍的,从而达到控制更加复杂和精确场景需求的目的。

在这里球体中我们添加一个Physics Field,而我们的在下面的BOX中重设我们的物理场,使得Box中完全不受到力场影响。

添加力场

最简单的添加力场的操作为ApplyPhysicsField

1
	void ApplyPhysicsField(bool Enabled, EFieldPhysicsType Target, UFieldSystemMetaData* MetaData, UFieldNodeBase* Field);
  1. Enabled控制是否这个力场会真正起作用。
  2. EFieldPhysicsType是物理的类型,主要有一下类型
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
enum EFieldPhysicsType
{
	Field_None					,
	Field_DynamicState		,//可用于将几何体集状态更新为睡眠(Sleeping)、运动(Kinematic)、静态(Static)、动态(Dynamic)或用户定义状态。
	Field_LinearForce		   ,//可用于在几何体集中用户指定的位置和方向应用力。
	Field_ExternalClusterStrain,//用于在给定体积内应用张力,若该值大于几何体集 破坏阈值,将释放簇碎片,
	Field_Kill				   ,//此类场可用于在刚体落入指定体积内时停止模拟刚体
	Field_LinearVelocity	   ,//可用于沿起点和终点生成冲击速度。
	Field_AngularVelociy	   ,//可用于在给定半径内生成冲击速度。
	Field_AngularTorque		,//可用于将指定(或随机)扭矩量应用到刚体,以获得更有趣的模拟。
	Field_InternalClusterStrain,//	用于对场内所有刚体设置张力值。
	Field_DisableThreshold	,//可用于在超过定义阈值时禁用刚体模拟。将完全移除模拟中的已禁用刚体。移除后可利用场(非碰撞)重新激活。
	Field_SleepingThreshold	,//可用于在超过定义阈值时让刚体开始睡眠。场和碰撞可唤醒并继续模拟睡眠刚体。
	Field_PositionStatic	   ,//
	Field_PositionAnimated	,//
	Field_PositionTarget	   ,//
	Field_DynamicConstraint	,//可用于约束几何体集的部分。
	Field_CollisionGroup	   ,//用于影响指定碰撞组中的几何体集。
	Field_ActivateDisabled	,//重新激活被禁用粒子。
	//256th entry
	Field_PhysicsType_Max          
};

Sleep和KillField将会去重置物理,当它的速度低于某个阈值的时候,Sleeping中的刚体是可以重新被唤醒。Disabled是指进入到这个区域后会去掉所有的物理模拟,其是完全被去除而不能重新唤醒, 3. MetaData,待研究 4. Field,场的属性。UFieldNodeBase是所有力场的父类,其子类场的类型非常丰富,例如,CullingField,UBoxFalloff,UNoiseField等等,也可以自己进行扩展。例如我们需要一些放射状的力场,Noise的力场,还可以指定是否衰减。

局部破碎

如果我们想要实现在实时过程中,指定某个区域有力场,例如射击击中的地方破碎,我们应当动态spawn一个FieldSystemActor,在其世界位置生成一个Field。

局部不破碎

使用锚场(Anchor Fields) 可用于将几何体集部分锁定在一处,而对几何体集其余部分实施碎裂。 锚场与多数场系统节点不同,由于须在模拟前建立连接图表,因此必须在构造阶段建立锚场。 因此,其逻辑在 场系统Actor 蓝图的 构造脚本 中定义,并使用 添加场命名(Add Field Command) 节点(无法使用 应用物理场(Apply Physics Field))进行引用。模拟时,如启用 分簇,在使用 张力场 应用 张力 前,抛锚几何体集将保持静态。

Niagara

Niagara系统可以与Chaos系统做出非常友善的交互,我们可以从外部蓝图中传入Niagara系统Chaos的数据,然后就可以根据Chaos的破碎位置来进行粒子的发射,这对于产生一些粉尘和小碎块非常的有帮助。 https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210104141417.png

并且我们使用Niagara 的Collision和其拖尾的Event效果,可以做出浓烟爆炸等特殊的破碎效果。

性能-GeometryCollection 缓存

要改善较大模拟时的性能,建议尝试将运行时模拟改为缓存模拟。 缓存模拟适用于发生在背景中或未涉入玩家交互的破坏。Chaos未来的版本将支持在模拟和缓存模拟之间动态切换。 需首先记录缓存模拟,才能进行播放。

https://papalqiblog.oss-cn-beijing.aliyuncs.com/blog/picture20210105144235.png