FreeShoot

视频教程已同步发布至B站:https://www.bilibili.com/video/BV1S14y1P7Z4

手部模型

导入模型

先创建一个../assets文件夹,导入手部模型,直接导入所有

image-20221031073801146

再创建一个Animations文件夹,导入动画

image-20221031074056011

注意这里的导入选项

image-20220902212350803

添加材质

创建一个材质M_Hand,导入的三个贴图放到材质里,并按照如下排布

image-20221031074317402

image-20221031074413131

把这个材质应用到手上

image-20220902212615864

更换模型

添加两个操作映射

image-20220913231241051

接下来开始调试手部模型,打开VRPawn

image-20220914222945834

选中MotionControllerLeft和Right,添加骨骼网格体组件,并对其命名

image-20220914223110485

image-20220914223055453

分别对左右网格体进行如下设置

1
2
3
(X=-6.200000,Y=0.100000,Z=5.600000)
(Pitch=-53.700000,Yaw=2.640000,Roll=265.900000)
(X=1.050000,Y=-1.050000,Z=1.050000)

image-20220914223207642

1
2
3
(X=-6.200000,Y=0.100000,Z=5.600000)
(Pitch=-53.000000,Yaw=-13.500000,Roll=106.800000)
(X=1.050000,Y=1.050000,Z=1.050000)

image-20220914223224065

关闭HMD的可视

image-20220914223255454

禁止MotionControllerLeft和Right显示设备模型

image-20220914223314511

然后编译保存,你将会发现你的控制器变成了手部模型,效果如下

image-20220914223507426

手部动画

接下来开始创建动画,创建动画蓝图,并命名为BP_HandAnim

image-20220914223917119

创建一个枚举,命名为Enum_HandAnim

image-20220915223839389

image-20221101091726289

再创建一个枚举,命名为Enum_ObjectType

image-20221101091740088

双击进入BP_HandAnim,创建两个变量,注意命名和变量类型

image-20220915224537647

配置状态和状态转换规则

image-20220915225640993

依次双击每个状态机,配置相应资产,以下以Open为例

image-20220915225828753

配置每个状态之间的过渡规则,这里以Open到Grip的状态过渡规则为例,双击那个双箭头的小图标,然后添加如下规则

image-20220915225737449

image-20221026232938410

接下来双击VRPawn,设置左右手的动画类

image-20220915230106362

给VRPawn设置一些蓝图(注意变量提升之后要重命名和更改类别为HandAnimations,是类别不是变量类型)

image-20220915230925562

创建下面6个布尔变量

image-20220915231209637

添加如下蓝图

image-20220915231622319

image-20220915231806224

image-20220915231945419

最后打开BP_HandAnim,我们来写一些状态转换的蓝图控制代码

具体转换规则定义如下

image-20221101092235291

先转换类型,创建三个函数

image-20221101092114815

image-20221101092135817

image-20221101092159590

然后写事件图表(蓝图较长,各位请自行拼接)

image-20221101092320525

image-20221101092336437

以上蓝图确认无误之后,你的双手就可以按照上面定义的规则来做出相应的动画了

使用武器

新增GrabType枚举

image-20221102075952142

设置插槽

打开手部骨骼模型,为拿枪的动作添加一个插槽

image-20220917101716773

image-20221102080043736

把枪放进来

image-20221102085251059

把枪移动到合适的位置

image-20221102085315996

image-20221102085332938

然后把资产移除,并把动画换成默认

image-20221102085359795

使用插槽

打开GrabComponent,编写如下蓝图

image-20220917103844547

注意,上面的每一次SET都是一次变量提升,记得修改它的变量名,跟上图保持一致。这些蓝图的意义是让我们在每一次Grab的时候能够调用对这些变量的引用

然后创建一个宏,方便获取插槽的位置和旋转,注意命名要保持一致

image-20220917105459673

接下来编辑TryGrab函数,将红色框的蓝图复制一份到蓝色框的位置,并连接Gun

image-20221102085600810

编写如下蓝图,它对应Gun这一块(注意SocketName,一定要和前面的插槽名字保持一致。观察蓝图,其实很多地方都是一样的,多用复制粘贴)

image-20221102085637515

然后编辑TryRelease函数

image-20221102085713735

image-20220917110417952

创建资产

image-20221102085923865

image-20221102085937301

放进场景里

image-20221102090012157

混合空间

还没完,我们还需要创建一个混合空间

image-20220917112626380

image-20220917112710490

命名为BS_Object_Anim,然后打开它

image-20221102090131149

打开BP_HandAnim,进入Object状态,删掉原来的ANIM_OK_Grip序列播放器,编写如下蓝图

image-20220917113603370

接着你可以再次运行查看效果,不出意外应该是一切正常(出意外了就好好检查一下过程吧,代码是不会骗人的,害)

image-20221102090514111

手枪

image-20221102232920436

继承接口,从系统提供的样例中复制红色框的函数,然后创建一个Fire函数

image-20221102233033520

按照思维导图的思路,编写Fire函数蓝图

image-20221102233105880

其中击中效果的具体实现如下

image-20221102233129173

路径追踪的代码如下

image-20221109071908406

敌人

创建一个Drone蓝图(注意这是个Pawn,不是Actor)

image-20221103214114965

image-20221103221443585

爆炸效果

敌人被击中后需要播放爆炸效果,给DronePawn创建一个Explode函数

image-20221103215252984

被击中

让枪支可以击中Drone,并运行击中效果

image-20221103221526542

image-20221103221504770

然后把Drone放到场景里,就可以用手枪击中了,步枪也是如此

image-20221103221550283

巡逻

添加导航组件,放到路面上,按p建,会发现与地面重合的部分变绿了,绿的部分就说明可以导航

image-20221103230657953

如果发现有路沿没办法被覆盖,可以调整一下项目设置

image-20221005174122883

调整好之后再按一下P键就可以让绿色消失了

然后创建一个Actor,命名为PatrolPoint,也叫巡逻点,主要用于定位,不用写什么功能

image-20221005183442175

image-20221103230812174

然后互相指定为对方的NextPoint

image-20221005190928883

然后在DronePawn中,创建一个宏

image-20221103231228322

在事件中应用

image-20221103231029795

添加控制朝向的蓝图

image-20221103231123899

接下来给Drone创建一个移动组件

image-20221005174403615

指定Goal Actor

image-20221103231257592

这些个操作的主要原理是:设定GoalActor为初始巡逻点,然后敌机就会在游戏启动的时候移动过去,移动到巡逻点之后,会将GoalActor设置为下一个巡逻点,然后继续移动,如此往复。

激怒

我们希望敌机被打了之后就变红,实现过程如下:

给敌机创建一个材质实例

image-20221006181615716

可以看到这里用于控制颜色的字段是TeamColor

image-20221006182501932

我们需要在游戏运行的时候给他创建动态的材质实例

打开DronePawn的构造脚本,编写如下蓝图

image-20221006182610520

然后修改Drone代码,新增一个自定义事件

image-20221104085520114

修改受伤函数

image-20221104085826573

修改构造函数

image-20221104085539937

然后在Fire中应用一下

image-20221104085640441

游戏模式

如果所有的敌机都被消灭了,且自身没有被一半的敌机击中,就算赢,否则就算输

创建一个GameHUD

image-20221105154336026

在VRPawn中创建一个控件组件,应用这个GameHUD

image-20221105154548933

打开默认游戏模式VRGameMode,记录目前剩余的敌机数量和被击中的数量,满足条件时就结束游戏

image-20221105155656281

image-20221105155839854

image-20221105155848118

被击中时也需要记录

image-20221105155714390

给Drone创建一个碰撞器

image-20221105155736007

image-20221105155752407

步枪

手枪是单发,步枪是连发的

先复制手枪蓝图,配置如下步枪蓝图

image-20221102233300909

配置瞄准镜

image-20221102233324364

加上弹夹

image-20221102233347357

出射点往前放

image-20221102233406495

配置手部插槽

image-20221102233457451

完善开枪逻辑,创建所需变量

其中FireButtonPressed默认为False

FireRate为0.1

CanFire为True

image-20221102233542039

image-20221102233630457

修改Fire函数

image-20221102233654850

然后放在场景里就可以了

image-20221102233727919

霰弹枪

复制手枪蓝图,修改对应骨骼

image-20221105222813965

修改Fire函数,把下面的原有的代码都折叠成Grape Shot函数,然后添加循环发射代码

image-20221105222909302

下面这一段基本不变

image-20221105222937190

修改修改Perform Line Trace函数,生成随机子弹路径,其中霰弹系数代表子弹之间的稀疏程度,可自行调节

image-20221105223153436

配置场景

在虚幻市场中下载这个场景,并将之添加到初始项目里

image-20220929221412057

打开这个地图的关卡蓝图

image-20220929222101289

把下面这一段都删掉

image-20220929222136688

然后把这个电影序列也删掉

image-20220929222157999

找到全局后期处理体积,把lens flares的强度取消,这样镜头前就不会出现光晕

image-20220929224611571

取消自动曝光

image-20220929225025841

复制一下外面的地面,把胡同口堵住,形成一堵墙

image-20220929225715703

调节星星的亮度

image-20221108091654395

在场景中放三个箱子,在箱子上分别放置手枪、步枪和霰弹枪

image-20221109071608482

image-20221109071627698

给场地上铺一层导航网格,设置单元高度为50

image-20221109071727868

再给场景加上一些Drones

image-20221109071758753

最后指定相应的游戏模式

image-20221109071818429

整个游戏就大功告成了!