当前位置: 首页 > news >正文

北京燕化工程建设有限公司网站7块钱建购物网站

北京燕化工程建设有限公司网站,7块钱建购物网站,上传wordpress,山东省交通厅建设网站首页在正常的RPG游戏中,都存在一个类别就是属性伤害,比如,在一个游戏里面有一个火属性的技能,它造成的伤害就是火属性类型的,并且它还有可能有附加伤害,比如给予目标一个灼烧效果,每秒造成多少的火属…

在正常的RPG游戏中,都存在一个类别就是属性伤害,比如,在一个游戏里面有一个火属性的技能,它造成的伤害就是火属性类型的,并且它还有可能有附加伤害,比如给予目标一个灼烧效果,每秒造成多少的火属性伤害。目标角色会有一个火属性伤害抵抗,根据百分比减少伤害。
比如英雄联盟技能伤害区分物理伤害和魔法伤害,有些技能能够造成两种伤害,比如卡特和永恩。
接下来,我们为游戏的伤害增加属性。

增加新的技能类

首先,我们基于自定义的技能类,创建一个派生的子类,专门用于处理具有伤害的技能。基类作为所有技能的基类,有可能技能时回血的,那么它的伤害相应的属性是使用不到的,属于浪费。
在这里插入图片描述
取名为RPGDamageGameplayAbility 专门用于处理伤害的技能的基类
在这里插入图片描述
记得将投掷技能释放物的类继承修改掉
在这里插入图片描述
将设置伤害的GE配置项从UProjectileSpell里面移到伤害类,并将基类上的伤害设置删除掉,为了能够让技能实现多种类型的伤害,我们通过一个Map来创建一个配置,可以在Map中设置多种伤害类型,并设置对应需造成的伤害。
在这里插入图片描述

增加对应的属性抗性标签

既然要增加伤害的类型,我们则需要增加对应的伤害类型以及类型抗性
打开我们之前在C++创建标签的文件RPGGameplayTags.h,先增加伤害类型

	FGameplayTag Damage; //伤害 标签FGameplayTag Damage_Fire; //火属性伤害 标签FGameplayTag Damage_Lightning; //雷属性伤害 标签FGameplayTag Damage_Arcane; //魔法伤害 标签FGameplayTag Damage_Physical; //物理伤害 标签

在cpp文件中,增加标签注册

	GameplayTags.Damage = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Damage"),FString("伤害标签"));GameplayTags.Damage_Fire = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Damage.Fire"),FString("火属性伤害"));GameplayTags.Damage_Lightning = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Damage.Lightning"),FString("雷属性伤害"));GameplayTags.Damage_Arcane = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Damage.Arcane"),FString("魔法伤害"));GameplayTags.Damage_Physical = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Damage.Physical"),FString("物理伤害"));

然后增加抗性标签

	//属性伤害抗性FGameplayTag Attributes_Resistance_Fire; //火属性伤害抵抗 标签FGameplayTag Attributes_Resistance_Lightning; //雷属性伤害抵抗 标签FGameplayTag Attributes_Resistance_Arcane; //魔法伤害抵抗 标签FGameplayTag Attributes_Resistance_Physical; //物理伤害抵抗 标签

并注册

	/* 属性抗性标签 */GameplayTags.Attributes_Resistance_Fire = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Resistance.Fire"),FString("火属性抗性"));GameplayTags.Attributes_Resistance_Lightning = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Resistance.Lightning"),FString("雷属性抗性"));GameplayTags.Attributes_Resistance_Arcane = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Resistance.Arcane"),FString("魔法伤害抗性"));GameplayTags.Attributes_Resistance_Physical = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Resistance.Physical"),FString("物理伤害抗性"));

设置完成伤害类型和对应的抗性标签后,我们还需要将其对应起来,我们增加一个Map标签

TMap<FGameplayTag, FGameplayTag> DamageTypesToResistance; //属性伤害标签对应属性抵抗标签

并在注册完成后,将其一一对应起来

	/* 将属性和抗性标签对应 */GameplayTags.DamageTypesToResistance.Add(GameplayTags.Damage_Fire, GameplayTags.Attributes_Resistance_Fire);GameplayTags.DamageTypesToResistance.Add(GameplayTags.Damage_Lightning, GameplayTags.Attributes_Resistance_Lightning);GameplayTags.DamageTypesToResistance.Add(GameplayTags.Damage_Arcane, GameplayTags.Attributes_Resistance_Arcane);GameplayTags.DamageTypesToResistance.Add(GameplayTags.Damage_Physical, GameplayTags.Attributes_Resistance_Physical);

这样,就完成了标签的添加。

增加抗性属性

标签添加完成,我们还需要在AttributeSet里面增加对应的抗性属性,用于记录当前角色抗性值,如果想完整的查看,请查看此文章 20. UE5 RPG创建次级属性并实现设置,下面我们快速实现抗性属性的添加。

	/** 属性伤害抗性*/UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_FireResistance, Category="Resistance Attributes")FGameplayAttributeData FireResistance; // 火属性抗性ATTRIBUTE_ACCESSORS(URPGAttributeSet, FireResistance);UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_LightningResistance, Category="Resistance Attributes")FGameplayAttributeData LightningResistance; // 雷属性抗性ATTRIBUTE_ACCESSORS(URPGAttributeSet, LightningResistance);UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_ArcaneResistance, Category="Resistance Attributes")FGameplayAttributeData ArcaneResistance; // 魔法抗性ATTRIBUTE_ACCESSORS(URPGAttributeSet, ArcaneResistance);UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_PhysicalResistance, Category="Resistance Attributes")FGameplayAttributeData PhysicalResistance; // 物理抗性ATTRIBUTE_ACCESSORS(URPGAttributeSet, PhysicalResistance);

然后增加对应的复制函数

	UFUNCTION()void OnRep_FireResistance(const FGameplayAttributeData& OldFireResistance) const;UFUNCTION()void OnRep_LightningResistance(const FGameplayAttributeData& OldLightningResistance) const;UFUNCTION()void OnRep_ArcaneResistance(const FGameplayAttributeData& OldArcaneResistance) const;UFUNCTION()void OnRep_PhysicalResistance(const FGameplayAttributeData& OldPhysicalResistance) const;

在cpp中实现复制函数

void URPGAttributeSet::OnRep_FireResistance(const FGameplayAttributeData& OldFireResistance) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, FireResistance, OldFireResistance);
}void URPGAttributeSet::OnRep_LightningResistance(const FGameplayAttributeData& OldLightningResistance) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, LightningResistance, OldLightningResistance);
}void URPGAttributeSet::OnRep_ArcaneResistance(const FGameplayAttributeData& OldArcaneResistance) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, ArcaneResistance, OldArcaneResistance);
}void URPGAttributeSet::OnRep_PhysicalResistance(const FGameplayAttributeData& OldPhysicalResistance) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, PhysicalResistance, OldPhysicalResistance);
}

在同步时,设置同步

void URPGAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{Super::GetLifetimeReplicatedProps(OutLifetimeProps);...//抗性属性DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, FireResistance, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, LightningResistance, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, ArcaneResistance, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, PhysicalResistance, COND_None, REPNOTIFY_Always);...
}

在初始化时,将标签和属性对应

URPGAttributeSet::URPGAttributeSet()
{const FRPGGameplayTags& GameplayTags = FRPGGameplayTags::Get();//------------------------------------------------属性标签和属性关联------------------------------------------------.../** Resistance Attribute*/TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Fire, GetFireResistanceAttribute);TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Lightning, GetLightningResistanceAttribute);TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Arcane, GetArcaneResistanceAttribute);TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Physical, GetPhysicalResistanceAttribute);
}

这样就完成的属性标签的创建。

在UI上面显示抗性值

接下来,我们要在UI面板显示角色的对不同类型的伤害的抗性值。如果查看UI面板的具体实现,看我之前的文章:23. UE5 RPG制作属性面板(一)
首先,我们在设置角色次级属性的GE里面增加对应的计算
在这里插入图片描述
这里我设置的火属性抗性和雷属性抗性都是基于加的抗性点来实现
在这里插入图片描述
而魔法抗性和物理抗性则基于智力和护甲值来设置,这里我也是随便填写的数值用于测试,就不截全了。在实际项目中,这个计算通常需要策划的配合。
在这里插入图片描述
我们还需要在DA_AttributeInfo文件中增加对应在UI上显示的标签对应的名称和描述,它是被设置在BP_AttributeMenuController上面的,实现这个也是方便属性列表设置时,我们只需要在列表上面设置标签名称,函数会帮我们实现下面的工作。
在这里插入图片描述
然后就是打开UI用户空间,在属性列表增加四个子项,用于显示抗性数值。
在这里插入图片描述
通过我们之前的设置,现在只需要修改标签,其它的工作就不用做了
在这里插入图片描述
接着运行项目查看UI上面是否正确的显示了对应的属性
在这里插入图片描述

实现伤害类型的计算

首先我们要重新设置技能伤害,并设置类型,比如我们创建的火属性类型技能,伤害是火属性的,我们设置火属性伤害标签,并设置上对应的伤害
在这里插入图片描述
接下来,就需要去代码里将逻辑重新修改掉。
在生成发射物的技能类里,我们创建GE的地方,将属性的伤害通过SetByCaller方式设置给GE
我们可以遍历将在技能列表上设置的所有的属性类型和伤害设置过去。

//设置技能伤害 SetByCaller获取 通过Tag
const FRPGGameplayTags GameplayTags = FRPGGameplayTags::Get(); //获取标签单例
for(auto& Pair : DamageTypes)
{const float ScaledDamage = Pair.Value.GetValueAtLevel(GetAbilityLevel()); //根据等级获取技能伤害UAbilitySystemBlueprintLibrary::AssignTagSetByCallerMagnitude(SpecHandle, Pair.Key, ScaledDamage);
}

设置属性伤害就算完成了,接下来我们转到ExecCalc_Damage.cpp文件里,增加对目标的属性获取
首先在静态实例类里面增加对抗性属性设置

struct SDamageStatics
{...DECLARE_ATTRIBUTE_CAPTUREDEF(FireResistance);DECLARE_ATTRIBUTE_CAPTUREDEF(LightningResistance);DECLARE_ATTRIBUTE_CAPTUREDEF(ArcaneResistance);DECLARE_ATTRIBUTE_CAPTUREDEF(PhysicalResistance);SDamageStatics(){//参数:1.属性集 2.属性名 3.目标还是自身 4.是否设置快照(true为创建时获取,false为应用时获取)...DEFINE_ATTRIBUTE_CAPTUREDEF(URPGAttributeSet, FireResistance, Target, false);DEFINE_ATTRIBUTE_CAPTUREDEF(URPGAttributeSet, LightningResistance, Target, false);DEFINE_ATTRIBUTE_CAPTUREDEF(URPGAttributeSet, ArcaneResistance, Target, false);DEFINE_ATTRIBUTE_CAPTUREDEF(URPGAttributeSet, PhysicalResistance, Target, false);}
};

然后在构造时,将参数添加到捕获列表中

UExecCalc_Damage::UExecCalc_Damage()
{//添加监听...RelevantAttributesToCapture.Add(DamageStatics().FireResistanceDef);RelevantAttributesToCapture.Add(DamageStatics().LightningResistanceDef);RelevantAttributesToCapture.Add(DamageStatics().ArcaneResistanceDef);RelevantAttributesToCapture.Add(DamageStatics().PhysicalResistanceDef);
}

我本来想把Map写到静态实例类里,发现在代码的运行过程中,单例实例创建时,标签还没有设置成功,这就导致在单例实例里面无法获取到标签,所以,我转到了Execute_Implementation函数中,创建Map的原因是,我们这样就不需要在for循环中进行二次遍历了,只需要通过Map获取对应的Value即可。

	//存储标签和属性快照对应的MapTMap<FGameplayTag, FGameplayEffectAttributeCaptureDefinition> TagsToCaptureDefs;//添加标签和属性快照对应的数据TagsToCaptureDefs.Add(GameplayTags.Attributes_Resistance_Fire, DamageStatics().FireResistanceDef);TagsToCaptureDefs.Add(GameplayTags.Attributes_Resistance_Lightning, DamageStatics().LightningResistanceDef);TagsToCaptureDefs.Add(GameplayTags.Attributes_Resistance_Arcane, DamageStatics().ArcaneResistanceDef);TagsToCaptureDefs.Add(GameplayTags.Attributes_Resistance_Physical, DamageStatics().PhysicalResistanceDef);

由于我们在函数内无法获取技能设置了几种伤害类型和伤害,所以,我们要把所有的类型都遍历到,所以,我们从标签单例中获取到伤害类型和抵抗类型的对照标签Map,并将其遍历

for(const TTuple<FGameplayTag, FGameplayTag>& Pair : GameplayTags.DamageTypesToResistance)

然后通过抗性类型的标签去获取快照引用

const FGameplayTag DamageType = Pair.Key;
const FGameplayTag ResistanceType = Pair.Value;
//检查对应的属性快照是否设置,防止报错
checkf(TagsToCaptureDefs.Contains(ResistanceType), TEXT("在ExecCalc_Damage中,无法获取到Tag[%s]对应的属性快照"), *ResistanceType.ToString());
//通过抗性标签获取到属性快照
const FGameplayEffectAttributeCaptureDefinition CaptureDef = TagsToCaptureDefs[ResistanceType];

获取到快照了,我们可以通过快照去获取目标的抗性值,这里限制到0-100是防止预算出错,超一百了,会出现攻击负值的情况,应用到角色那就是加血了。

//获取抗性值
float Resistance = 0.f;
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(CaptureDef, EvaluationParameters, Resistance);
Resistance = FMath::Clamp(Resistance, 0.f, 100.f); //将抗住限制在0到100

接着通过SetByCaller获取到伤害类型的伤害,如果没有设置,获取的值将为0

		//通过Tag获取对应伤害类型的值,如果没设置SetByCaller将获取0float DamageTypeValue = Spec.GetSetByCallerMagnitude(DamageType);

最后,计算出能够造成的伤害,并将伤害叠加做后续计算

		//通过抗性计算出能够对角色造成的伤害值DamageTypeValue *= (100.f - Resistance) / 100.f;//将每种属性伤害值合并进行后续计算Damage += DamageTypeValue;

计算完成以后,我们可以进行debug测试,这是火球术,火属性伤害,本来能造成的伤害为5,受到抵抗后,伤害减少了百分之11.5,最总火球术造成的伤害为4.425
在这里插入图片描述

http://www.yayakq.cn/news/301501/

相关文章:

  • 网站被k湖北响应式网站设计制作
  • 建立互联网公司网站wordpress4.9主题
  • 福州建设招聘信息网站查询网站备案进度查询
  • 网站开发价格评估杭州 专业网站建设 网络服务
  • 可以做产品推广的网站网站建设运营合同
  • 微山网站建设哪家便宜展厅设计公司网站
  • 如何做网站pptwordpress登录logo修改
  • 建筑设计招标网站成都网站建设中心
  • 科技公司网站网页wordpress标签墙
  • 图片网站如何优化电子商务的营销模式有哪些
  • 高端品牌网站建设方案网站开发项目报价
  • 网站备案的网站名称在线看mv视频网站入口软件下载
  • 手游网络游戏排行榜上海seo顾问推推蛙
  • 网上做兼职网站有哪些工作互联网创业项目的效果
  • 品牌网站建设服务商wordpress 网店主题
  • 网站左侧图片悬浮代码wordpress island
  • 成都哪里有做网站建设的wordpress发布文章关键词
  • 论坛网站推广做微课的网站
  • 中国城市建设控股集团有限公司网站设计之家logo设计
  • 网页编辑实践报告什么是seo关键词
  • 南京房地产网站建设wordpress 直达链接
  • 网站快速推广排名技巧文创产品设计调研
  • 做网站开发要具备什么知识保利集团网页设计作业
  • 松江九亭网站建设怎么查网站是哪个建站公司做的
  • 怎样做网站手机客户端免流网站开发
  • 下载 iis 网站企业文化网站建设
  • 潍坊知名网站建设抢注qq空间专属域名网站
  • 温州网站建设培训学校wordpress 时尚主题
  • 前端网站建设和维护美食网站建设策划书
  • 电商网站页面布局南京建筑人才招聘网