野外生存游戏【3. 采集系统】

本章逻辑繁杂,细节很多,本文更多的是作为大纲指引和逻辑梳理,可能笔记中还存在部分操作上缺漏,还请多包涵,有意者可下载工程文件自行对照学习

UE版本:5.2.1

斧头砍树

image-20230903203222253

这一块的逻辑很直观,首先准备挥舞斧头的蒙太奇动画,然后按下鼠标就运行动画,同时检测斧头前端是否有树木,有的话就根据伤害和树木的健康度来分析状态

蒙太奇如下,根据动画直接生成,在斧头挥舞到最前端的时候添加一个MontageNotify,后面用于检查碰撞

image-20230903203649553

image-20230903203927728

于此同时,第一人称和第三人称的动画蓝图要配置默认插槽,配置了才能正常运行蒙太奇

image-20230903204104945

打开 BP_FirstPersonCharacter,新增一个点击事件,通过接口调用对应武器

image-20230903204324327

这里给 BPI_EquipableItem 新增几个函数如下

image-20230903204436360

BP_FirstPersonCharacter 继承的 BPI_SurvivalCharacter 接口也要新增几个函数

image-20230903205459432

UseItemInterface 在 BP_TP_Hachet 的实现如下

image-20230903205353549

找到对应的蒙太奇之后,又回到了 BP_FirstPersonCharacter 发起调用

image-20230903205631360

其中结束动画和 Notify 通知函数的实现逻辑在 BP_TP_Hachet 的实现如下

image-20230903205822138

这里的 Structure 通道是新建的,用于区分可以被砍的物体

image-20230903205944811

物资增加、树木倒地

目录结构

上面挥舞斧头之后,会通过 Notify 检测到被砍的物体,然后需要根据伤害和健康值来增加对应的物资,当被砍物体的健康值低于0了之后,就要倒地消失

为了区分和管理这些可以被砍的物体,我们创建了下面这个结构,与斧头等装备系统类似,都是一层层的向下继承,目录结构如下

image-20230903210706793

以 BP_HarvestingMaster 为基类的继承关系如下

image-20230903211008634

核心原理

这里分为 ChildClasses 和 Desturetables 是因为一个是被砍之前的状态,一个是砍了之后的状态。ChildClasses 就是摆在场景里(称作摆件),Desturetables 需要在物体生命值降低到 0 以后,根据受力方向倒地(称作替死鬼)

好了,我们回到 BP_TP_Hachet 的核心砍树逻辑,大致原理如下:

先根据接口找到被砍的是哪个,然后判断被砍了之后还能不能活,如果还能活,那就扣生命值,并加物资;如果活不了了,那就销毁场景中的摆件,获取当前角色的方向,生成替死鬼,施加受力,倒地消失

image-20230903212109005

image-20230903212318707

增加物资

这里面有不少细节,我们首先看 BP_LargeItemMaster,它继承了BPI_Larger_Item,实现接口,返回自身引用

image-20230903211732000

还新建了一个 DT_LargeItemResources 数据表,表示这个物体被砍了一次可以获得3个物资,其中 RowName 就是生成之后的类名

image-20230903212555766

要注意,这里插件的类型要是我们上面定义的 Structure 才行

image-20230903214434564

获取到被砍物体的信息之后,需要通过接口找到 BP_FirstPersonCharacter 来放入库存,并展示通知

具体逻辑如下

image-20230903212905635

image-20230903212922655

image-20230903212931439

这里的展示 UI 还是老样子,通过 PlayController 调用 Widget,只不过这里新增了一个通知 Widget,但是不用慌,很简单,操作如下

image-20230903213215221

因为本身通知也只有几秒,所以图标和文字都是通过绑定来实现的,不影响性能

只不过有一点额外操作,新增了一个动画,两秒后透明度要逐渐降为0

image-20230903213405955

彻底变为透明之后,就销毁这个通知组件

image-20230903213432912

最后把这个 Widget 挂载到主场景里就好了,通过一个 VerticalBox 来承载

image-20230903213534212

image-20230903213547460

然后给 PlayController 调用,整个流程就串起来了

image-20230903213628507

替死鬼

上面那些都是砍了之后没砍倒的逻辑,接下来分析一下砍倒之后的逻辑

先回顾一下 BP_TP_Hachet 里面销毁摆件,生成替死鬼的逻辑

image-20230903213913637

里面从数据表里面读取出了要生成的 class,以棕榈树为例,它的目录位置在这里

image-20230903214039763

它的父级的父级(BP_DesturctableHarvestable)定义了一些变量,供子类使用

image-20230903214150441

倒地逻辑在 BP_DestructableTree 中实现,创建了四个胶囊碰撞体,用于受力和倒地

这几个胶囊体要打开模拟物理,重量可以自由设计(案例中是四个子胶囊体都是400,主干2000)

image-20230903214549018

最后给替死鬼补充一个挨打接口就好了

image-20230903214714137

image-20230903214723845

树木溶解

目前树木倒地之后消失的有些突兀,这里可以加一个溶解的过程

找到树木的材质,加上这么一段

其中暴露出来的 Dissolve 参数就是用于实现溶解的

image-20230904173522979

image-20230904173545046

然后在 BP_PalmDestMaster 里面通过时间轴来控制 Dissolve参数,编写这么一段溶解的逻辑就可以了

image-20230904173712566

image-20230904173815372

新增镐子

image-20230904174032412

新增物体的逻辑十分简单,上面的结构都设计好了,只需要导入模型,然后加入到数据表里,并补充对应的item蓝图即可

image-20230904174245098

下面这两蓝图都是继承自 BP_TP_Hachet 和 BP_FP_Hachet 的

image-20230904174300284

注意这里改一下

image-20230904174344845

高级计算逻辑

新增两个枚举

image-20230905114722884

image-20230905114748193

修改数据表里的 PerferToolType

image-20230905115128191

修改 BP_TP_Hachet 里面的砍树逻辑,根据服务器费率,装备种类,装备材质和伤害值,来计算获得的物品数量

image-20230905114927967

image-20230905115228568

最后别忘了把 BP_TP_Stone_Hatchet 的 ToolType 修改正确

image-20230905115316593

到此这段逻辑就弄好了,这个时候用斧头砍树收获的木头就比用镐子砍收获的多了

image-20230905115421574

采集石头

效果预览

image-20230905153153685

先从Quixel Bridge里面随便找个石头模型

image-20230905151201250

导入之后自动生成一下碰撞

image-20230905151231079

接着使用 Chaos 创建碎石效果,将这个模型拖到场景里面,进入 Fracture Mode

image-20230905151314795

点击 New,将生成的文件存入下面文件夹

image-20230905151531156

生成好之后返回 Selection Mode,然后创建一个 fieldSystemActor

image-20230905151730769

image-20230905151945570

接着再创建一个 BP_DestructableRock (继承自BP_DesturctableHarvestable),用于生成破碎效果

image-20230905152248525

基于这个类,再生成一个 BP_BeachRockDest01 子类,放入Rock文件夹,要放在数据表里面用

image-20230905152358168

最后打开 Items 数据表,创建两条物品数据

image-20230905152424693

打开 LargeItemResources 表,创建一条矿石资源数据

image-20230905152456942

修复 BP_TP_Hachet 里面的小问题

image-20230905152601677

将矿石放入场景里面,就可以挖石头了

采集植物

首先还是从Quixel Bridge里面找个植物模型导入到场景里,然后用 chaos 创建对应的 Geometry Collection,步骤和上面一样,这里就不再重复做

image-20230905165354365

创建一个 DT_GroundResources 数据表

image-20230905165517768

先在 DT_Items 里面创建两个物品资源数据

image-20230905165610934

然后到 DT_GroundResources 里面创建采集数据

image-20230905165632145

数据都准备好之后,创建蓝图,继承自 BP_GroundItemMaster

image-20230905165740726

image-20230905165821739

其中 BP_GroundItemMaster 继承了一个新接口 BPI_GroundItem 用于返回引用

image-20230905165920586

然后创建 Destruct 蓝图

image-20230905170103122

以及对应的子类

image-20230905170137379

完事之后进入 BP_FirstPersonCharacter 里面编写对应的采集逻辑,按 E 采集即可,里面的函数逻辑与上文的树木采集和石头采集十分类似,这里就不多分析,聪明的你肯定一看就懂😘

image-20230905170522575

image-20230905170449420

image-20230905171351478

image-20230905171400552

补充视觉和声音

这一块的逻辑比较简单,就不详细解释了,实现的效果是在砸石头的时候有一些灰尘和声音,石头破碎了也有粒子效果,主要用到了以下资产

image-20230908163030900

image-20230908162923157