网站关键词怎么做效果好,玻璃钢产品哪个网站做推广好,浙江信息网查询系统,苏州公司建设网站首页在上一篇文章中#xff0c;我们实现了敌人受到攻击后会播放受击动画#xff0c;并且还给角色设置了受击标签。并在角色受击时#xff0c;在角色身上挂上受击标签#xff0c;在c里#xff0c;如果挂载了此标签#xff0c;速度将降为0 。 受击有了#xff0c;接下来我们将…在上一篇文章中我们实现了敌人受到攻击后会播放受击动画并且还给角色设置了受击标签。并在角色受击时在角色身上挂上受击标签在c里如果挂载了此标签速度将降为0 。 受击有了接下来我们将实现角色的死亡逻辑角色血量为0或者小于0时我们将触发它的死亡功能。
实现死亡
在战斗接口类里增加一个虚函数0 是我们无法创建函数的实现必须在子类里面去覆写它。
virtual void Die() 0;在角色基类里面覆写
virtual void Die() override;接着我们增加一个在每个客户端上执行的函数被Die函数调用。 NetMulticast设置后这个函数被调用时将在服务器执行然后复制到每个客户端。和它对应的还有Server只在服务器运行Client只在调用此函数的客户端运行这种情况的函数实现需要在后面加上_Implementation Reliable: 这是一个传输属性表示该函数的数据应该以可靠的方式发送。 UFUNCTION(NetMulticast, Reliable)virtual void MulticastHandleDeath();这样Die函数只会在服务器调用我们将只需要服务器调用的函数写到此函数内 比如武器分离然后调用每个端都会运行的函数MulticastHandleDeath()
void ACharacterBase::Die()
{//将武器从角色身上分离Weapon-DetachFromComponent(FDetachmentTransformRules(EDetachmentRule::KeepWorld, true));MulticastHandleDeath();
}在MulticastHandleDeath()函数里我们开启武器和角色的模拟效果并关闭碰撞体的碰撞防止它影响武器和角色
void ACharacterBase::MulticastHandleDeath_Implementation()
{//开启武器物理效果Weapon-SetSimulatePhysics(true); //开启模拟物理效果Weapon-SetEnableGravity(true); //开启重力效果Weapon-SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); //开启物理碰撞通道//开启角色物理效果GetMesh()-SetSimulatePhysics(true); //开启模拟物理效果GetMesh()-SetEnableGravity(true); //开启重力效果GetMesh()-SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); //开启物理碰撞通道GetMesh()-SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block); //开启角色与静态物体产生碰撞//关闭角色碰撞体碰撞通道避免其对武器和角色模拟物理效果产生影响GetCapsuleComponent()-SetCollisionEnabled(ECollisionEnabled::NoCollision);
}在敌人里面我们需要额外实现一些内容就是小怪死亡后我们要在一定时间后将其清除掉。 UPROPERTY(EditAnywhere, BlueprintReadOnly, CategoryCombat)float LifeSpan 5.f; //设置死亡后的存在时间在敌人基类里面也覆盖Die函数并在死亡时设置它的清除时间
void AEnemyBase::Die()
{SetLifeSpan(LifeSpan);Super::Die();
}接下来在AttributeSet的PostGameplayEffectExecute函数里增加Die函数调用的逻辑处理我们在死亡时调用即可 if(Data.EvaluatedData.Attribute GetIncomingDamageAttribute()){const float LocalIncomingDamage GetIncomingDamage();SetIncomingDamage(0.f);if(LocalIncomingDamage 0.f){const float NewHealth GetHealth() - LocalIncomingDamage;SetHealth(FMath::Clamp(NewHealth, 0.f, GetMaxHealth()));const bool bFatal NewHealth 0.f; //血量小于等于0时角色将会死亡if(bFatal){//调用死亡函数ICombatInterface* CombatInterface CastICombatInterface(Props.TargetAvatarActor);if(CombatInterface){CombatInterface-Die();}}else{//激活受击技能FGameplayTagContainer TagContainer;TagContainer.AddTag(FMyGameplayTags::Get().Effects_HitReact);Props.TargetASC-TryActivateAbilitiesByTag(TagContainer); //根据tag标签激活技能}}}接着可以编译运行我们攻击敌人查看它死亡时是否能够模拟布娃娃效果并且在设置的清除时间后被正确清除
溶解材质
死亡效果已经实现了但是小怪死亡定时直接清除掉显得太突兀大部分游戏中的做法就是使用溶解效果来实现它的缓慢消失的效果。 所以我们需要一个溶解材质在UE里面我们可以通过连连看来实现蓝图类型的节点实现此功能。 首先我们创建一个材质 我们需要一个透明裁剪的材质将混合模式修改为已遮罩Masked 溶解需要一个值来控制它平滑的过渡但是每个材质的溶解的范围不同所以我这里设置了两个值开始结束然后用lerp实现从开始到结束的溶解过程。 然后从一张扰动图上面获取颜色进行对比度增强获取到透明度值我们可以通过修改溶解值来实现渐变过程。 CheapContrast是简单的调整对比度的节点函数第一个传入颜色第二个传入对比强度来获取增加对比度后的结果。 然后我们还需要一个就是溶解边缘发光的效果这个将透明度作为UV的U去采样另外一张扰动图然后增强对比度获取到边缘设置到自发光上面实现效果。 材质我们设置了如何查看放到模型上面的效果呢我们可以在MI材质实例这里选择预览网格体进行查看 然后调整start和end的值保证Dissolve能够在0的位置时没有溶解效果而Dissolve值变为1时角色被全部溶解掉
实现溶解效果
溶解材质我们有了接下来就是如何实现从普通材质切换到溶解材质并实现通过程序修改Dissolve溶解的数值。 我们打开敌人的骨骼网格体发现它身上就一个材质我们需要通过代码去实现切换模型的材质并实现对材质的属性修改。 打开角色基类我们在里面增加两个参数用于设置角色和武器的溶解材质 UPROPERTY(EditAnywhere, BlueprintReadOnly)TObjectPtrUMaterialInstance DissolveMaterialInstance;UPROPERTY(EditAnywhere, BlueprintReadOnly)TObjectPtrUMaterialInstance WeaponDissolveMaterialInstance;然后增加一个溶解函数在角色死亡时调用
void Dissolve(); //溶解效果溶解是需要一个时间过程我准备在蓝图里面实现时间轴这样比较方便所以增加一个蓝图实现的函数这个函数在代码里调用在蓝图实现。参数我们设置了一个数组因为不确定有几个材质需要修改有可能只有一个角色的有可能角色和武器两个所以我们直接传递数组去修改。 UFUNCTION(BlueprintImplementableEvent)void StartDissolveTimeline(const TArrayUMaterialInstanceDynamic* DynamicMaterialInstance);然后在溶解的实现这里我们首先判断是否设置了对应的材质如果设置了则创建一个实例设置给角色然后将材质添加到数组中最后调用时间轴函数
void ACharacterBase::Dissolve()
{TArrayUMaterialInstanceDynamic* MatArray;//设置角色溶解if(IsValid(DissolveMaterialInstance)){UMaterialInstanceDynamic* DynamicMatInst UMaterialInstanceDynamic::Create(DissolveMaterialInstance, this);GetMesh()-SetMaterial(0, DynamicMatInst);MatArray.Add(DynamicMatInst);}//设置武器溶解if(IsValid(WeaponDissolveMaterialInstance)){UMaterialInstanceDynamic* DynamicMatInst UMaterialInstanceDynamic::Create(WeaponDissolveMaterialInstance, this);Weapon-SetMaterial(0, DynamicMatInst);MatArray.Add(DynamicMatInst);}//调用时间轴渐变溶解StartDissolveTimeline(MatArray);
}最后就是在死亡函数中调用溶解
void ACharacterBase::MulticastHandleDeath_Implementation()
{//开启武器物理效果Weapon-SetSimulatePhysics(true); //开启模拟物理效果Weapon-SetEnableGravity(true); //开启重力效果Weapon-SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); //开启物理碰撞通道//开启角色物理效果GetMesh()-SetSimulatePhysics(true); //开启模拟物理效果GetMesh()-SetEnableGravity(true); //开启重力效果GetMesh()-SetCollisionEnabled(ECollisionEnabled::PhysicsOnly); //开启物理碰撞通道GetMesh()-SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block); //开启角色与静态物体产生碰撞//关闭角色碰撞体碰撞通道避免其对武器和角色模拟物理效果产生影响GetCapsuleComponent()-SetCollisionEnabled(ECollisionEnabled::NoCollision);//设置角色溶解Dissolve();
}代码部分我们已经完成了接下来编译打开UE在敌人基类里面覆写StartDissolveTimeline 创建一个时间轴 修改好名称我们每次调用让其冲开始位置更新 双击时间轴打开然后添加一个轨道重新命一个名称 鼠标右键可以添加关键帧 添加完关键帧可以点击此处自动缩放 记得选中所有的点让其自动圆滑处理 处理完成我们得到了一条圆滑的曲线时间轴 这样我们就完成了时间轴的制作。退出以后我们让时间轴去更新材质这里有个小技巧就是可以增加线的固定点让线不那么复杂 因为程序不知道材质里面的参数所以我们需要使用设置浮点型的参数 在材质上面也显示了当前参数的类型我们只需要将Dissolve修改从0到1就可以实现这个在时间轴里面的值也是这么设置的。 我们只需要遍历数组设置对应的材质即可。 完成以后我们需要在对应的敌人类里面去设置对应的角色和武器的材质 接下来就是运行测试效果了如果效果正确证明我们实现了对应的效果