UE4 可交互植被项目

任务一、实现一个力对树木的冲击效果

思路:

按1键时在红点出生成一个风力的蓝图(Force_Impulse BP)并在该点产生一个特效

在Force_Impulse BP的BeginPlay中实现三个功能:

1、配置参数

先拿到世界中的树木生成器蓝图(Tree Manager BP),

UE4 可交互植被项目_第1张图片

调用Tree Manager BP的Add Impulse函数,配置好风力的点Location,风力强度Strength,风力半径Radius,配置TimeLineComponent

UE4 可交互植被项目_第2张图片

这里可以看到设置了TimeLine的播放速率(Set Play Rate),设置TimeLine曲线(Set Float Curve),设置了风力的Location和风力的半径Radius放到了一个材质参数集中(ForceParameters)的参数Foce1_Loc和参数Force1_Radius 中(通过Set  Vector Parameter  Value函数)

UE4 可交互植被项目_第3张图片

ForceParameters里的参数配置如下:

UE4 可交互植被项目_第4张图片

播放TimeLine,把曲线的输出值乘以风强度ForceStrength赋给了材质(ForceParameters)的参数Foce_Strength中,由此可见,Force_Strength不是静态在ForceParameter中设定的,而是在蓝图中动态赋值到参数中的

2、拿到范围内的所有叶子组件蓝图,调用该蓝图里的从风力中生成落叶,生成废墟,生成水果三个函数

找到半径范围内(MultiSphereTraceByChannel)的所有物体,起点和终点设置为一个点,设置搜索半径即可输出所有的物体,遍历所有的Hit物体,拿到Hit信息,Break分离出HitComponent,  转成叶子蓝图的ComponentFoliageComp_Tree_BP

UE4 可交互植被项目_第5张图片

然后调用叶子蓝图中的从风力中生成落叶,生成残渣,生成水果三个函数

我又仔细看了下,好像确实是有风时,有落叶和残渣掉下来

(1)在生成落叶函数中:在叶子组件旁边播放落叶的特效

(2)在生成残渣(小树枝等)函数中:计算 生成残渣位置,残渣的位置的x和y是该树static mesh的x和y,z等于mesh的z*scale大小*2*0.6+位置的z

UE4 可交互植被项目_第6张图片

力的冲击影响因子Impulse Influence(树的位置和风力位置距离长度除以风的范围半径),如果风的强度(Impulse Strength和力的冲击影响因子Impulse Influence)大于最小下落的推力(Min Impulse Strength to Fall),就分别拿到所有Bark(不知道翻译叫什么)和落叶(Leaves)的材质,如果风力大就生成残渣多一点如果,风力小就生成少一点,更加真实

UE4 可交互植被项目_第7张图片

这里对废渣设置了初始力的推力=风力和废渣位置的方向*风力强度*风力影响因子*系数

UE4 可交互植被项目_第8张图片

(3)在生成水果函数中:计算生成位置,力的冲击影响因子,同上生成不同水果

 

3、销毁Force_Impulse_BP

 

 

所有的Actor解析:

1、残渣Actor(只有一个StaticMesh)

在构造函数中设置mesh和动态材质,然后StaticMesh开启物理模拟,StaticMesh设置Linear Damping

在BeginPlay中,先延迟0.1秒(这个挺重要的,有时候不延迟不会走后面逻辑),给StaticMesh去Add Impulse,再Add Angular Impulse In Radians,再延时五秒,关闭物理模拟,再把StaticMesh的Collision Response to AllChannels全部Ignore。

再延时10秒,用一个TimeLine输出动态参数改变材质里Fade渐变值,最后销毁

2 水果Actor 基类(Tree Fruit BP)

和上面一样

3、风的蓝图(Wind_BP)

在构造函数中传入初始化参数到WindParameters材质参数集中

UE4 可交互植被项目_第9张图片

在WindParameters中保存了风的所有变量参数,因为材质参数集中没有vctor,所以用了一个RGBA中的RGB来保存Vector的xyz

UE4 可交互植被项目_第10张图片

改变风力的方向和强度函数:

无非就是TimeLine将变量传到参数集中

UE4 可交互植被项目_第11张图片

4 树的叶子Component (FoliageComp_Tree_BP)

Turn into Choppable Blueprint函数:

该函数作用是删除该树的实例(拿到Component的Index),并生成一个可砍伐的树木,将所有属性传给他

UE4 可交互植被项目_第12张图片

SpawnLeavesFromImpulse和SpawnDebrisFromImpulse和SpawnFruitsFromImpulse函数(已介绍过)

5 树木生成器TreeGenerator_BP

该类是由许多SplineComponent组成,来拼成枝干的形状

UE4 可交互植被项目_第13张图片

在该类下有许多可调节参数:

树干的所有参数,水果的所有参数,树枝的所有参数,树叶的所有参数

   UE4 可交互植被项目_第14张图片

 UE4 可交互植被项目_第15张图片UE4 可交互植被项目_第16张图片

随便调节参数都会有不同效果,比如枝数为9和5的效果

UE4 可交互植被项目_第17张图片   UE4 可交互植被项目_第18张图片

介绍里面的所有函数:

AddTrunkStart函数(树桩起始位置):

一方面添加一个SplineComponent,设置两个点的位置(index 0和index 1),TrunkStartHeight的默认值为50,

UE4 可交互植被项目_第19张图片

TrunkStartHeight为50和200的对比

UE4 可交互植被项目_第20张图片      

另一方面添加SplineMeshComponent,根据LOD的不同设置不同的StaticMesh和Material

UE4 可交互植被项目_第21张图片

不同的LOD等级的StaticMesh的三角数和顶点数也不一样( LOD技术指用若干不同复杂度的模型来表示同一对象的技术。此技术主要根据视点距离对象位置的变化调用不同复杂度的模型,即在较远时调用低复杂度模型,在较近时调用高复杂度模型。

UE4 可交互植被项目_第22张图片  UE4 可交互植被项目_第23张图片

再将木桩的起点和终点的设置为Spline的起点和终点,让曲线的样式显示出来,设置Scale

UE4 可交互植被项目_第24张图片

TrunkStartScale为0.7和0.1的对比

UE4 可交互植被项目_第25张图片     UE4 可交互植被项目_第26张图片

AddTrunk函数:

先介绍Trunk Point Amount变量,表示主树干部分有多高,点数越多,树干越长

UE4 可交互植被项目_第27张图片

Trunk Point Amount为7和2的区别

UE4 可交互植被项目_第28张图片              UE4 可交互植被项目_第29张图片

Trunk Irregularity(树干的扭曲程度)参数为20和100的区别:

 UE4 可交互植被项目_第30张图片         UE4 可交互植被项目_第31张图片

在该函数中TrunkSpline从TrunkStart的终点开始

UE4 可交互植被项目_第32张图片

遍历Trunk Point Amount个点,给TrunkSpline添加每个点,该点的位置和Trunk Irregularity(树干的扭曲程度,扭曲越大,x和y偏移就越厉害)有关

UE4 可交互植被项目_第33张图片

遍历每个点,缓存每个点到起点的距离/整个spline长度,用数组保存,用于计算scale

UE4 可交互植被项目_第34张图片

再遍历一次该Trunk树干的所有节点,为每一段设置一个SplineMeshComponent

UE4 可交互植被项目_第35张图片

同样根据不同LOD设置不同Mesh,和Material

UE4 可交互植被项目_第36张图片    UE4 可交互植被项目_第37张图片   UE4 可交互植被项目_第38张图片

最后得到两个相邻节点的起点和终点,赋给SplineMeshComponent,至于每一段的Scale,当然是越后的段,Scale越细

 

 

如何将材质参数集的参数应用到树木中?

在其中一种树的StaticMesh中可以看到叶子的材质

在叶子材质中

拿到Parent(Leaf_M),在该材质中叶子的摇摆偏移计算全在世界位置偏移中

UE4 可交互植被项目_第39张图片

逻辑很多,该材质读取了ForceParamters的所有参数设置叶子的抖动,

UE4 可交互植被项目_第40张图片

如果把世界位置偏移去掉,那么游戏里只有树干在动,叶子不动

想禁用树干的摇摆就把树干的材质偏移逻辑禁用

 

该项目中学到的一些函数:

1、获取Static Mesh的体积,拿到Extent就可以得到长宽高的值

UE4 可交互植被项目_第41张图片

2、生成一个点的范围内的随机点的值,比如在一片区域内随机位置生成敌人有用

UE4 可交互植被项目_第42张图片

3、创建一个动态材质实例

UE4 可交互植被项目_第43张图片

4、拷贝动态材质参数

UE4 可交互植被项目_第44张图片

5、mesh设置材质

UE4 可交互植被项目_第45张图片

6、Mesh设置线性阻尼Linear Damping

UE4 可交互植被项目_第46张图片

关于Linear Damping

7、设置mesh的角度冲量,有一种瞬间爆开的感觉

UE4 可交互植被项目_第47张图片

8、拿到一个类中的值的属性

UE4 可交互植被项目_第48张图片

9、通过索引从InstancedStaticMeshComponent中哪个实例的信息

UE4 可交互植被项目_第49张图片

在UInstancedStaticMeshComponent中可以看到,该类作用是相同StaticMesh要渲染多次(估计渲染时的渲染顺序有关),在他下面有个    TArray PerInstanceSMData;这个就应该是保存所有实例的那个数组吧

/** A component that efficiently renders multiple instances of the same StaticMesh. */
UCLASS(ClassGroup = Rendering, meta = (BlueprintSpawnableComponent), Blueprintable)
class ENGINE_API UInstancedStaticMeshComponent : public UStaticMeshComponent
{
	GENERATED_UCLASS_BODY()
	
	/** Needs implementation in InstancedStaticMesh.cpp to compile UniquePtr for forward declared class */
	UInstancedStaticMeshComponent(FVTableHelper& Helper);
	virtual ~UInstancedStaticMeshComponent();
	
	/** Array of instances, bulk serialized. */
	UPROPERTY(EditAnywhere, SkipSerialization, DisplayName="Instances", Category=Instances, meta=(MakeEditWidget=true, EditFixedOrder))
	TArray PerInstanceSMData;

该函数的作用如下

	/** Returns the instances with instance bounds overlapping the specified sphere. The return value is an array of instance indices. */
	UFUNCTION(BlueprintCallable, Category = "Components|InstancedStaticMesh")
	virtual TArray GetInstancesOverlappingSphere(const FVector& Center, float Radius, bool bSphereInWorldSpace=true) const;

10  想获得一个半径范围的所有物体,有以下三种函数:

UE4 可交互植被项目_第50张图片

通过SphereOverlapActors输出的是所有Actor的数组,但是本项目中如果是画刷刷出来的树,得到的actor都是同一个actor,他们的区分是通过Hit信息中Hit Component来区分是哪种类型的树以及Hit Item来区分是该类型下的第几棵树

UE4 可交互植被项目_第51张图片

因此通过MultiSphereTraceByChannel设置起点和终点为同一个点,既能输出所有的物体信息,而且也能得到每个Hit信息

11  计算旋转角,也即取得旋转角的向量

c++源码(.h和.cpp):

	/** Get the X direction vector after this rotation */
	UFUNCTION(BlueprintPure, meta=(DisplayName = "GetRotationXVector", Keywords="rotation rotate cast convert", BlueprintAutocast), Category="Math|Rotator")
	static FVector Conv_RotatorToVector(FRotator InRot);
KISMET_MATH_FORCEINLINE
FVector UKismetMathLibrary::Conv_RotatorToVector(FRotator InRot)
{
	return InRot.Vector();
}

如果想把这个向量转成Rotation,再调用RotationFromXVector

UE4 可交互植被项目_第52张图片

12  我想看残渣TreeDebris_BP中的Material是在哪里赋值的,查找引用,发现为空,居然没有给它设置,究竟是怎么给它赋值的呢?

UE4 可交互植被项目_第53张图片

答案是生成该蓝图的时候就作为参数传进去了,而且查找引用也查找不到,所以如果一个变量查找引用没有设置该变量时,在查找生成该蓝图的所有引用,说不定能找到

UE4 可交互植被项目_第54张图片

13 得到范围内的所有Static Mesh,拿到它的Instance Index

UE4 可交互植被项目_第55张图片

14 switch的用法

UE4 可交互植被项目_第56张图片

如果输入是index,如上图,也可将index改成想要的枚举格式,如下

UE4 可交互植被项目_第57张图片

也可将变量改为其他类型,如枚举对应不同static mesh

UE4 可交互植被项目_第58张图片     UE4 可交互植被项目_第59张图片

15 add 各种component

UE4 可交互植被项目_第60张图片

16 设置splineComponent点的位置

UE4 可交互植被项目_第61张图片

17 设置spline的起点和终点(如果发现spline曲线画出的线是直线不是曲线,要把Tangent乘个系数

UE4 可交互植被项目_第62张图片

18 将多种数据放到一个结构体变量保存

UE4 可交互植被项目_第63张图片

19 数组添加元素还能这样用

UE4 可交互植被项目_第64张图片

你可能感兴趣的:(ue4)