尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

UE5FPS游戏开发教程(三)

UE5FPS游戏开发教程(三) 提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档文章目录前言一、开火射击模块1.制作开火蒙太奇动画2.使用MetaSound实现音效3.添加开火Niagara特效4.实现开火时生成弹壳5.实现武器后坐力效果6.添加击中特效和音效7.优化生成机制8.实现弹孔痕迹前言一、开火射击模块1.制作开火蒙太奇动画在制作开火射击系统之前我们先将BP_FPSPlayer中的SpawnWeapon函数中动态创建Weapon对象的逻辑修改一下。我们现在是在SpawnWeapon函数中通过生成Actor节点中的Class参数然后选择一个蓝图类来作为武器。但是后续我们会有多个武器所以我们可以将这个生成Actor节点的Class参数设置为SpawnWeapon函数的输入参数然后这样就能在调用SpawnWeapon函数时设置当前武器蓝图了。然后我们在事件图表中将SpawnWeapon函数的输入参数设置为BP_VIRTUS蓝图类。我们还需要在SpawnWeapon函数中将生成Actor节点的返回值转换为BP_WeaponBase基础武器对象然后将返回对象设置为变量CurrentWeapon表示当前武器。这样做的原因和C中继承类似因为后续所有武器都会继承自BP_WeaponBase蓝图类所以我们将当前武器变量的类型也设置为BP_WeaponBase类型因为我们不知道后续角色选中的武器到底是什么类型的所以我们只能将当前武器类型设置为它们的统一父类BP_WeaponBase这样不管武器是什么类型的都不会出错。然后当我们在其它地方已经确认角色的武器类型时想要拿到角色的当前武器对象我们就可以先获取BP_FPSPlayer对象中的CurrentWeapon变量然后将该变量转换为具体的武器类型。所以说这就和C中的继承的使用方法类似了。此时Weapon变量就不再使用了我们直接将Weapon变量删除即可。因为Weapon变量之前是BP_VIRTUS类型的它只能代表维克多这一个武器型号后续其它武器型号就不能使用这个变量了。然后我们在ABP_FPSPlayer动画蓝图中将Weapon变量替换为CurrentWeapon变量。下面我们就来制作开火功能。我们在Input目录下新建一个输入操作命名为IA_Fire表示开火输入。然后设置它的值类型为布尔。然后我们打开输入映射情境IMC_FPSInput再添加一个数据映射IA_Fire绑定到鼠标左键上。然后我们在BP_FPSPlayer中将IA_Fire事件节点添加上然后再添加两个变量IsFiring表示是否开火IsDead表示角色是否死亡。然后判断当开火按键按下时此时开火状态为false并且角色没有死亡时然后再判断当前角色并没有处于奔跑状态时就先把IsFiring设置为true表示进入开火状态后面再开始执行开火逻辑。然后我们在Code目录下新创建一个BluprintInterface文件夹用来存储蓝图接口然后我们创建一个蓝图接口命名为BI_Fire。然后双击打开BI_Fire蓝图接口设置函数名称为StartWeaponFire然后添加一个函数输入变量Player类型设置为BP_FPSPlayer。然后我们在BP_WeaponBase蓝图中点击类设置然后添加一个蓝图接口并且选择为前面创建的BI_Fire然后可以看到此时左侧就有一个StartWeaponFire接口了。我们双击一下接口就可以将它调取出来然后我们将事件StartWeaponFire的Player参数提升为变量。然后我们在BP_FPSPlayer蓝图中的开火逻辑后先创建一个StartWeaponFire节点然后将它的目标设置为CurrentWeapon因为我们在BP_WeaponBase蓝图中添加了这个StartWeaponFire蓝图接口所以可以设置StartWeaponFire节点的目标为BP_WeaponBase类型的对象而我们前面将CurrentWeapon变量的类型也设置为BP_WeaponBase类型了所以可以直接将CurrentWeapon变量连接到StartWeaponFire节点的目标引脚上。然后StartWeaponFire蓝图接口的输入参数Player我们设置为了BP_FPSPlayer类型并且此时我们在BP_FPSPlayer蓝图的事件图表中所以我们直接使用Self节点来设置StartWeaponFire节点的Player引脚即可。经过上面的一系列操作我们可以发现BP_FPSPlayer角色蓝图对象就传递到了BP_WeaponBase蓝图中了。即我们可以通过蓝图引脚来将两个没有联系的蓝图类联系到一起。例如我们在BI_Fire蓝图接口中实现了一个StartWeaponFire函数然后我们在BP_WeaponBase蓝图中添加了BI_Fire接口那么我们就能通过BP_WeaponBase蓝图对象来调用BI_Fire中的StartWeaponFire函数了然后StartWeaponFire函数有一个类型为BP_FPSPlayer的输入参数Player我们直接设置为Self。这样当点击鼠标左键时会执行BP_FPSPlayer蓝图中的IA_Fire事件然后就会执行该事件后面连接的StartWeaponFire函数然后就会执行BP_WeaponBase蓝图中的StartWeaponFire事件后的逻辑了。然后我们在BP_WeaponBase蓝图中新创建几个对象。我们将之前创建的Ammo对象重命名为CurrentAmmo表示当前弹夹中子弹数量然后新建一个TotalAmmo整型变量表示当前剩余多少子弹然后创建一个MagSize整型变量表示弹夹容量然后创建一个BaseDamage浮点型变量表示武器伤害然后创建一个FireRate浮点型变量表示武器射速。然后我们在BP_WeaponBase基础武器蓝图中写开火逻辑这样的话其它继承自BP_WeaponBase蓝图类的武器类就可以使用这个开火逻辑了。我们在开火之前需要先判断当前弹夹中是否还有子弹然后当弹夹中有子弹时我们就通过以事件设置定时器节点设置一个定时器然后该节点的Time引脚就是定时器执行速率我们设置为武器射速FireRate即可。然后该节点的Event引脚我们连接上新创建的FireInternal事件。当弹夹中没有子弹时我们需要播放一个类似三角洲中的弹夹没有子弹的音效。然后我们在FireInternal事件中添加两个播放蒙太奇节点一个表示开火时角色播放的开火动画一个表示开火时武器播放的开火动画。然后我们先设置第一个武器开火蒙太奇动画。播放蒙太奇节点的InSkeletalMeshComponent(传入一个骨骼网格体组件作为输入参数)引脚我们就连接Weapon骨骼网格体组件这表示当前武器的骨骼网格体。然后MontagetoPlay(待播放动画蒙太奇)引脚是要播放的动画资产因为角色每个状态的开火动画不一样所以我们先通过BP_FPSPlayer类型对象Player得到当前角色状态EPlayerState然后根据角色不同的状态设置相对应的开火动画。并且因为每个武器的开火动画都是不一样的所以我们这里不能设置角色每个状态的开火动画是定死的我们需要将每个状态的开火动画都提升为变量然后在外部根据具体武器来设置它的不同状态的开火动画。因为Run状态下没有办法开火所以这个状态我们就不设置开火动画了。然后我们来设置第二个角色开火蒙太奇动画我们先通过Player获取到角色手臂骨骼网格体Arm然后设置给播放蒙太奇的InSkeletalMeshComponent(传入一个骨骼网格体组件作为输入参数)引脚。然后MontagetoPlay(待播放动画蒙太奇)引脚的值和前面武器蒙太奇节点的同理都需要根据角色的状态使用不同的角色开火动画。然后我们将新创建的动画蒙太奇类型的变量名称都修改规范以便后续使用。然后此时我们来到BP_VIRTUS蓝图中点击类默认值然后在右侧细节面板中可以设置我们在BP_WeaponBase蓝图中创建的一些变量的值例如武器弹夹容量、武器伤害、武器射速等并且还可以设置当前维克多武器对应的角色不同状态下的开火动画等。然后我们在资产文件夹下的Player文件夹下面搜索Fire找到和Fire相关的动画序列。然后第一个ADS_Fire就是角色在瞄准状态下的开火动画第二个Fire就是角色在非瞄准状态下的开火动画即腰射。然后我们选中ADS_Fire动画序列右键创建动画蒙太奇名称不需要改这样就创建出了角色瞄准状态下的开火动画蒙太奇了。同理创建出非瞄准状态下的。然后我们在Weapon文件夹下面同理创建出维克多武器的瞄准状态下和非瞄准状态下的动画蒙太奇。然后我们在BP_VIRTUS蓝图中配置相对应的动画蒙太奇和维克多武器的相关参数。然后我们在ABP_FPSPlayer动画蓝图和ABP_VIRTUS动画蓝图中的状态窗口在输出姿势节点前面添加一个插槽节点这样动画蒙太奇才能正常播放。此时运行项目点击鼠标左键开枪时可以看到枪在抖动这就说明动画蒙太奇已经可以正常播放了。前面运行项目时点击鼠标左键一下枪就会一直抖动这是因为我们当前只做了开火逻辑没有做停火逻辑所以点击一下鼠标左键就会一直处于开火状态了。下面我们在BP_WeaponBase蓝图中将定时器提升为变量重命名为FireTimerHandle。然后我们新创建一个StopFire事件在该事件中通过FireTimerHandle变量调用定时器的以句柄清除定时器并使之无效节点来让开火定时器停止Looping循环这样就不会一直播放开火动画了。然后我们在BP_FPSPalyer蓝图中在IA_Fire事件的Completed后面通过CurrentWeapon变量调用BP_WeaponBase蓝图对象的StopFire事件来执行停火逻辑然后再设置IsFiring变量为false表示当前为停火状态。此时我们运行项目当前还存在两个问题一是开火动画的幅度很小所以开火时好像是枪在一直抖动。二是当长按鼠标左键时才可以播放开火动画松开鼠标左键时开火动画停止并且点击鼠标左键后开火动画是有延迟的。下面我们先解决开火动画延迟问题。这个延迟是因为在BP_WeaponBase中我们设置开火定时器时第一次点击鼠标左键开火后它也需要等待FireRate时间才会开火所以就有了延迟。所以我们只需要在每次点击鼠标左键时先执行一次开火事件FireInternal然后再设置开火定时器这样就可以解决开火延迟问题了。然后我们来解决开火时枪的动画幅度小的问题。我们找到前面创建的动画蒙太奇并打开然后将混入时的混合时间设置为0混合选项设置为线性。然后将混出时的混合时间设置为0.25混合选项设置为线性。前面创建的四个动画蒙太奇都需要进行这一步修改。此时运行项目可以看到开枪时动画的幅度就大一些了。2.使用MetaSound实现音效下面我们来制作开枪音效。在UE5里做音效逻辑一般有两种方式一种是传统的SoundCue另一种就是现在最新、最强大的MetaSound它可以实现更加复杂的音效效果。而SoundCue以前用的比较多它的逻辑比较固定扩展性也很有限。所以我们下面会使用更加先进的MetaSound来制作枪械音效。我们先在Weapon目录下创建一个MetaSound文件夹然后在MetaSound文件夹下面创建一个MetaSound源文件命名为MS_VIRTUS。然后打开MS_VIRTUS文件其中播放时节点就是只要这个MetaSound被触发了播放时节点后面的内容就会被执行。完成时节点就是告诉引擎什么时候这个音频能播放完然后引擎就会将这个音频文件给释放掉不再占用资源。输出单声道节点就是具体播放什么声音。我们添加一个随机获取(Float:Array)节点这个节点可以从输入数组中随机选取一个数组中的值然后输出。然后我们右键让输入数组提升为图表输入然后给输入数组添加两个索引分别设置为0.91.1。这样的话该节点就会随机输出0.9或1.1了。我们让该节点输出的值来作为后续枪声音效的音高这样枪声音高就不是一直不变的了而是随机的0.9或1.1了这样显得枪声更真实。然后我们再添加一个随机获取(WaveAsset:Array)节点这个节点可以从输入数组中随机选取一个数组中的音效文件然后输出该音效即达到枪械音效随机选择的效果。我们复制粘贴三个随机获取(WaveAsset:Array)节点因为我们有三重音效即子弹发射音、子弹爆发音环境回响等然后让这三种音效叠加来组成最后的开枪声音所以我们添加三个节点。然后将引脚连接上然后将这三个随机获取(WaveAsset:Array)节点的输入数组参数都提升为图表输入。然后我们设置第一个随机获取(WaveAsset:Array)节点的输入数组我们添加6个索引这里每一个索引就表示一个枪的音效然后开枪时随机播放这里面的6个音效。然后我们在资源文件夹中找到开枪音效文件将编号为1-6的音效文件分别设置给6个索引。然后同理设置第二个随机获取(WaveAsset:Array)节点的输入数组也是添加6个索引然后将编号为7-12的音频文件分别设置给6个索引这6个声音属于一次枪声中的另一个组成部分。然后同理设置第三个随机获取(WaveAsset:Array)节点的输入数组这个数组添加8个索引然后将剩下的8个音频文件设置给这8个索引。然后我们添加声波播放器(1.0单声道)节点然后复制三个声波播放器(1.0单声道)节点。前面我们使用随机获取(WaveAsset:Array)节点获取到音频文件然后再使用声波播放器(1.0单声道)节点来播放音频文件。为什么我们需要三个声波播放器(1.0单声道)节点呢这是因为枪声并不是一个单独的音频组成的它是这三个音频同时播放叠加组成的。然后我们还需要添加一个单声道混音器(3)节点来将前面的三个单声道音频混合在一起因为输出单声道节点只能输出一个音频所以我们需要通过单声道混音器(3)节点来将3个单声道音频混合为一个。当然也可以通过单声道混音器(5)节点来将5个单声道音频混合为一个如果我们有5个单声道音频的话。然后我们将第一个声波播放器(1.0单声道)节点的完成时引脚连接到完成时节点上因为第一个是枪声的回响音效它的时间比较长所以当第一个声波播放器(1.0单声道)节点播放完成时其它两个声波播放器(1.0单声道)节点肯定已经播放完成了所以我们只需将第一个节点的完成时引脚连接即可。我们可以通过音频资源文件看到每个音频的时长。这样当枪声的回响音效播放完成后UE5就会将MS_VIRTUS音频对象销毁了这样就能节省性能开销了。然后我们将随机获取(Float:Array)节点的随机音高输出值提升为图表变量。然后将该变量给声波播放器(1.0单声道)节点的音高频移偏移引脚。声波播放器(1.0单声道)节点的这个引脚是调整音频是偏明亮还是偏低沉的值越小声音越低沉值越大声音越明亮。以此我们来让枪声更加的随机性。即我们先通过随机获取(Float:Array)节点来随机获取到0.9或1.1然后将这个值设置为声波播放器(1.0单声道)节点的音高频移偏移值以此来达到枪声音效随机高频或低频这样能显得枪声更真实。我们可以点击绿色播放按钮来听我们制作的音效。然后我们在BP_WeaponBase蓝图的开火事件FireInternal后面添加一个播放音效2D节点然后设置资产为我们前面创建的MS_VIRTUS。这样每当FireInternal事件执行时就会通过播放音效2D节点来播放MS_VIRTUS中的音频。此时运行程序我们点击开火按键就可以听到有开枪声音了。3.添加开火Niagara特效下面我们来实现枪的开火特效。我们先将特效资源复制到项目根目录下的Content目录下。然后我们将BP_VIRTUS蓝图中Weapon骨骼网格体组件下的5个枪组件都剪切到BP_WeaponBase蓝图中的Weapon骨骼网格体组件下。因为这5个组件一般的枪械都会有所以我们直接在BP_WeaponBase蓝图基类中实现然后在继承自BP_WeaponBase蓝图基类的蓝图类中手动设置这些静态网格体组件所需要的静态网格体资源即可。然后选中BP_WeaponBase中的5个静态网格体组件将它们的静态网格体设为默认值。还需要注意这5个组件和Weapon组件的碰撞预设都设置为无碰撞。然后我们需要给BP_WeaponBase蓝图中的Weapon骨骼网格体组件设置维克多枪的骨骼网格体模型。这里我们只需要它的骨骼来进行一个占位即可因为没有骨骼的话我们就没有办法设置Weapon组件下的5个静态网格体组件的父项套接字了。设置好Weapon组件的骨骼网格体后我们将5个静态网格体的父项套接字还设置为和前面一样。这样当我们新创建一个武器蓝图时我们只需要在新蓝图中设置Weapon组件的骨骼网格体设置5个子组件的静态网格体即可。如果有的武器没有枪托或者瞄准镜时我们只需要不设置该子组件的静态网格体模型即可。在设置父项套接字时前面三角形图标表示插槽骨头图标表示骨骼。然后我们在BP_VIRTUS中设置Weapon组件的骨骼网格体模型和5个子组件的静态网格体模型。然后我们在BP_WeaponBase蓝图的开火事件FireInternal后面添加一个生成系统已附件节点然后资产选择VIRTUS开火特效。然后开火特效要附件在枪管组件上所以我们将Barrel组件连接到生成系统已附加节点的Attach to Component引脚上然后Attach Point Name插槽名称我们需要选择Barrel组件上的插槽名称。我们可以点击进入到维克多武器的枪管模型DMR-X_Barrel模型中然后看到该模型中有两个插槽Laser插槽是用来装镭射或者手电筒的Muzzle是枪口插槽。我们将开火特效附加到Muzzle插槽上即可所以我们在生成系统已附件节点的Attach Point Name参数中填写Muzzle。因为我们是在BP_WeaponBase蓝图中设置的生成系统已附件节点的Attach Point Name参数为Muzzle所以后续枪械的枪管模型中都需要有名称为Muzzle的插槽不然的话开枪特效就会绑定错误。然后运行项目我们就可以看到有开火特效了。如果我们想仔细观察开火特效位置对不对等我们可以一直按着开火按键然后按F8按键进入自由视角此时可以更好的观察开火特效等。如果我们感觉开火特效大小不合适烟雾浓度不合适等我们可以在特效中进行修改。4.实现开火时生成弹壳下面我们来实现每开火一次在抛弹口抛出一枚弹壳的效果。我们打开SK_MCX_VIRTUS骨骼网格体然后在body下添加一个插槽重命名为Casing将插槽位置移动到抛弹口附近确保红色轴线向外。然后我们在Weapon文件夹下面创建一个Actor蓝图类命名为BP_Casing这个就是弹壳蓝图。然后我们进入到BP_Casing蓝图添加一个静态网格体组件命名为Casing然后让Casing组件替代默认根组件。然后我们设置Casing组件的静态网格体为7.62x39类型子弹的模型。然后设置Casing组件的碰撞预设为Custom自定义然后将Casing与Pawn的碰撞设置为忽略即弹壳模型和角色模型不进行碰撞然后将模拟生成命中事件勾选上后续判断弹壳落地时要用到。然后我们添加一个发射物移动组件通过该组件来让弹壳发射出去。然后我们设置该组件的一些属性。发射物移动组件是UE内置专门用于子弹、箭矢、炮弹、投掷物这类抛射物体的移动组件该组件自动计算抛射体的飞行轨迹帮你处理初速度、重力下落、空气阻力、碰撞反弹、飞行朝向旋转甚至原生支持追踪导弹移动过程做扫描碰撞撞击物体后抛出OnProjectileHit命中事件用来写扣血、爆炸、销毁子弹逻辑。这里我们只让该组件简单的让弹壳以500初始速度发射出即可。然后我们再添加一个旋转移动组件后续通过该组件让弹壳抛出去时进行随机旋转。然后我们在BP_WeaponBase蓝图中的开火事件FireInternal后面添加一个从类生成Actor节点然后将Class类型选择为BP_Casing蓝图。这样的话每次执行FireInternal事件后就会通过从类生成Actor节点来动态生成一个BP_Casing弹壳对象。然后我们通过Weapon组件创建一个获取插槽变换节点来获取Weapon组件中的Casing插槽位置然后赋值给生成Actor BP_Casing节点的Spawn Transform引脚因为我们不需要调整缩放所以缩放引脚不需要连接。然后将插槽名称设置为前面在SK_MCX_VIRTUS中创建的Casing插槽的名称。这样的话通过从类生成Actor节点动态生成的BP_Casing弹壳对象的初始生成位置就是SK_MCX_VIRTUS骨骼网格体的Casing插槽的位置即就是维克多枪的出弹口位置。然后此时运行项目可以看到有弹壳生成并飞出去了但是弹壳是直挺挺的飞出去的。然后我们先在BP_Casing蓝图中选中Casing组件设置它的缩放为0.6以此来让弹壳缩小一些。然后我们通过RotatingMovement组件创建一个设置RotationRate节点用来设置弹壳对象旋转速率我们需要将这个旋转速率设置为随机值所以我们可以创建一个范围内随机浮点节点用来生成范围内的一个随机值。然后我们将这个随机值设置为弹壳对象各轴的旋转速率。这样的话当BP_Casing弹壳对象生成时就会通过RotatingMovement组件的RotationRate节点来设置该弹壳对象的旋转速率为一个-1800到1800之间的随机值。这样每个动态生成的弹壳对象就都会以随机旋转速率旋转了。此时运行项目再次点击开火此时可以看到弹壳就随机旋转了。然后我们选中BP_Casing蓝图然后设置它的初始生命周期为2.0这是设置BP_Casing蓝图对象的生命周期。因为弹壳生成后并且落地后不能一直在地上所以我们设置弹壳对象的生命周期为2.0即弹壳对象2秒后就自动销毁。这样就能减少性能消耗。然后我们选择Casing组件然后点击组件命中时添加一个组件命中时事件这个事件就是当弹壳与其它物体发生碰撞时就会被触发。然后我们创建一个在位置处生成音效的节点然后我们选择Bullet_Impact音效资产。然后我们再创建一个获取Actor位置节点来获取到BP_Casing对象的位置然后将位置赋值给在位置处生成音效节点的位置引脚。然后因为子弹落地时有反弹所以它会一直触发组件命中时事件那么每个弹壳对象就会一直播放弹壳落地音效这是不行的。所以我们通过Do Once节点让每个弹壳对象落地音效只执行一次即可。然后我们还需要设置当弹壳对象落地时让它的旋转速率设置为0即弹壳落地后就不需要再旋转了。此时运行项目可以看到每次开枪都会有弹壳生成并且弹壳落地后会发出响声而且弹壳对象2秒后就自动销毁了。如果我们感觉弹壳落地的声音太大的话我们可以通过在位置处生成音效节点的Volume Multiplier参数来修改音效的声音大小。5.实现武器后坐力效果下面我们来制作后坐力系统后坐力系统其实就是开枪时让角色的视角向上抬。我们在BP_WeaponBase蓝图的FireInternal事件后通过Player变量创建一个添加控制器Pitch输入节点通过该节点可以设置角色控制器的俯仰值即可以让角色视角的俯仰值进行改变我们通过让角色俯仰值向上抬以此来模拟开枪时武器垂直后坐力。制器Pitch输入节点的值设置为负数时表示向上抬。然后我们再创建一个添加控制器Yaw输入节点用来模拟开枪时武器水平后坐力这个后坐力我们使用范围内随机浮点节点来生成一个随机值作为水平后坐力。这样我们就做好了一个简单的后坐力系统。此时运行项目如果一直开枪的话可以看到角色视角会越来越向上抬。6.添加击中特效和音效下面我们使用射线检测功能来制作武器子弹击中效果即当开枪时我们就发射一个射线来模拟子弹。现在的大部分FPS游戏点击开枪时其实并没有发射子弹模型而是通过UE5的射线检测机制从屏幕中间发射了一条射线然后通过检测射线和哪里发生了碰撞然后就表示子弹击中了哪里然后就在碰撞的地方生成击中特效以此来到达子弹击中物体的效果和体验。我们在BP_WeaponBase蓝图的FireInternal事件后面添加一个按通道进行线条追踪节点该节点可以从Start位置到End位置之间形成一条检测射线。然后我们通过Player变量获取到角色摄像机然后再获取到摄像机的世界位置赋值给按通道进行线条追踪节点的Start引脚即将射线的起始位置设置为角色当前视角的中间即屏幕中间。我们现在的大多数FPS游戏的发射子弹其实都是从屏幕的中间发射的并不是从枪口发射的所以这里我们也从屏幕中间发射一条射线。然后射线的End参数需要结合子弹的射程地形等来计算。我们先通过摄像机对象获取当前角色向前向量然后再让角色向前向量乘一个整数这个整数其实就是子弹射程这里我们先设置为10000这样就得到子弹的向前向量了。然后我们让射线起始位置加上子弹向前的向量这样就得到射线的结束位置了。按通道进行线条追踪节点会在Start和End位置间生成一条射线当这条线段与其它物体产生碰撞时就会通过OutHit命中结果输出。我们可以通过Break Hit Result节点展开OutHit命中结果的值其中Location就是射线在什么位置发生了碰撞Phys Mat就是与什么材质发生了碰撞。下面我们创建一个在位置处生成系统节点该节点会在指定场景位置处生成Niagara系统即粒子特效。然后连接到按通道进行线条追踪节点的后面然后我们将OutHit的Location连接到在位置处生成系统节点的Location引脚然后我们选择一个特效DirtDirt特效就是子弹击中泥土时的特效这样当射线与物体产生碰撞时就会在碰撞位置生成一个Dirt特效了。此时运行项目当我们向下开枪时可以看到地面上就会有Dirt特效生成了。上面的Dirt是子弹击中泥土的特效当子弹击中金属时就不能使用这个特效了此时就需要通过OutHit的PhysMat物理材质对象来得到碰撞物体的物理材质然后再生成相对应的特效了。我们在项目设置的物理中设置物理材质的名称我们这里就先设置4个物理材质即Dirt泥土、Metal金属、Wood木头、Enemy敌人。当然我们自己还可以设置更多的材质我们的特效资源中还有击中玻璃的特效击中雪的特效击中水的特效这些物理材质我们可以后期自己添加上去。然后我们通过OutHit的PhysMat物理材质对象创建一个获取SurfaceType节点该节点获取了物理材质对象表面类型然后通过SurfaceType节点创建一个Switch节点可以看到Switch后面就有我们创建的每个物理材质的引脚了我们在对应的引脚后面连接对应的物理材质击中效果。然后我们通过OutHit的Normal结果创建一个利用X创建旋转节点然后连接到在位置处生成系统节点的Rotation引脚上这样就能保证特效一定是垂直于墙面进行发射的。然后我们在Code目录下创建一个Physics文件夹在该文件夹下面创建一个物理材质然后命名为PM_Dirt即泥土材质。然后我们双击进入PM_Dirt材质中将它的表面类型设置为Dirt。然后同理我们添加PM_Metal物理材质、PM_Wood物理材质、PM_Enemy物理材质然后将材质的表面类型设置为它们所对应的物理材质。然后我们在关卡中添加四个立方体将这四个立方体的物理材质重载分别设置为前面创建的PM_Dirt、PM_Metal、PM_Wood和PM_Enemy。此时运行项目然后将枪对准这四个立方体开枪时可以看到会生成不同的击中特效。然后我们运行结束后可以看到出现了错误然后点击错误后定位到Pyhs Mat这里这个错误就是当朝天空开枪时我们并没有设置天空这个物理材质所以当射线检测到和天空产生碰撞时此时获取到的Pyhs Mat物理材质对象是无效的所以就出现错误了。我们通过PhysMat物理材质对象来创建一个IsValid节点当判断PhysMat物理材质对象有效时才会执行后面的生成击中特效的逻辑。这样错误就解决了。然后我们来添加击中物体时的音效。我们在生成Dirt击中特效的节点后面创建一个在位置处生成音效的节点然后资产选择Dirt音效位置就是生成Dirt击中特效节点的位置即产生碰撞的位置。这样当射线检测到碰撞时在生成特效的同时还会生成击中音效。同理我们分别在Metal、Wood、Enemy击中特效节点的后面也添加一个在位置处生成音效节点资产选择相对应的Metal音效、Wood音效、Enemy音效位置就是生成击中特效节点的位置。如果我们感觉连线有些乱的话我们可以将Location提升为变量然后在需要位置的地方使用变量连线。7.优化生成机制前面我们通过判断PhysMat对象是否有效来决定是否生成击中特效和音效。但是这样的话当我们击中那些没有物理材质的模型时就不会生成击中特效了。这显然不是我们想要的我们想要的是当射线击中那些没有物理材质的模型时会触发一个默认的击中特效。这时我们就需要使用到OutHit的BlockingHit这个变量值了这个变量表示是否击中物体如果击中物体的话就为true。然后我们修改逻辑当击中物体时执行击中特效生成和音效生成。如果射线击中的是那些没有物理材质的模型时就生成默认的击中特效和音效。这里默认的击中特效和音效我们设置的是击中混凝土的特效和音效。我们上面使用了混凝土的击中特效和音效那么我们就将混凝土物理材质Concrete也添加到项目物理材质中然后在PyhsMat对象的Switch节点后面将默认引脚和Concrete引脚都连接到混凝土击中特效和音效节点上。这样的话当射线击中混凝土物理材质的物体或者没有物理材质的物体时都会生成混凝土击中特效和音效了。此时运行项目然后对着地面开枪因为地面我们没有设置物理材质此时对地面开枪时可以看到生成的是击中混凝土的特效和音效。8.实现弹孔痕迹下面我们来实现弹孔贴图的效果。我们先将Decals资源文件拷贝到项目根目录下的Content目录下。然后在BP_WeaponBase蓝图的FireInternal事件后添加一个从类生成Actor节点即在每个物理材质的生成击中音效节点的后面连接从类生成Actor节点。然后我们选择类的类型为BP_BulletDecal这个就是普通弹孔的痕迹然后我们将弹孔对象位置也设置为击中特效生成的位置旋转也和击中特效的一致因为弹孔对象也需要垂直于墙面。此时我们运行项目可以看到击中物体后物体上就会有弹孔了。我们看到前面设置的弹孔类BP_BulletDetal其实是一个蓝图类打开这个蓝图类可以看到里面就创建了一个贴图对象BulletDecal然后设置了贴图对象的随机旋转和随机大小。我们在弹孔类BP_BulletDetal中选中BulletDetal贴图对象然后可以看到它的贴花材质是Concrete混凝土材质弹孔。如果我们击中的是Metal金属或者Wood木头的话那么弹孔对象的贴花就不能是混凝土贴花了我们可以通过生成Actor BP_BulletDecal节点的返回值获取到BP_BulletDecal蓝图中的贴图对象BulletDecal然后通过设置贴花材质节点来设置Metal贴花或者Wood贴花。因为Dirt泥土击中时弹孔不明显击中敌人时没有弹孔所以这两个物理材质我们先不设置弹孔贴花。此时运行项目可以看到击中混凝土、木头和金属材质的物体生成的弹孔是不一样的。
返回列表