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

54. UE5 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
在这里插入图片描述

相关文章:

54. UE5 RPG 增加伤害类型

在正常的RPG游戏中&#xff0c;都存在一个类别就是属性伤害&#xff0c;比如&#xff0c;在一个游戏里面有一个火属性的技能&#xff0c;它造成的伤害就是火属性类型的&#xff0c;并且它还有可能有附加伤害&#xff0c;比如给予目标一个灼烧效果&#xff0c;每秒造成多少的火属…...

llama3 微调教程之 llama factory 的 安装部署与模型微调过程,模型量化和gguf转换。

本文记录了从环境部署到微调模型、效果测试的全过程&#xff0c;以及遇到几个常见问题的解决办法&#xff0c;亲测可用&#xff08;The installed version of bitsandbytes was compiled without GPU support. NotImplementedError: Architecture ‘LlamaForCausalLM’ not sup…...

C++三剑客之std::any(二) : 源码剖析

目录 1.引言 2.std::any的存储分析 3._Any_big_RTTI与_Any_small_RTTI 4.std::any的构造函数 4.1.从std::any构造 4.2.可变参数模板构造函数 4.3.赋值构造与emplace函数 5.reset函数 6._Cast函数 7.make_any模版函数 8.std::any_cast函数 9.总结 1.引言 C三剑客之s…...

【C语言】8.C语言操作符详解(2)

文章目录 6.单⽬操作符7.逗号表达式8.下标访问[]、函数调⽤()8.1 [ ] 下标引⽤操作符8.2 函数调⽤操作符 9.结构成员访问操作符9.1 结构体9.1.1 结构的声明9.1.2 结构体变量的定义和初始化 9.2 结构成员访问操作符9.2.1 结构体成员的直接访问9.2.2 结构体成员的间接访问 6.单⽬…...

vivado 物理约束KEEP_HIERARCHY

KEEP_HIERARCHY Applied To Cells Constraint Values • TRUE • FALSE • YES • NO UCF Example INST u1 KEEP_HIERARCHY TRUE; XDC Example set_property DONT_TOUCH true [get_cells u1] IOB Applied To Cells Constraint Values IOB_XnYn UCF Examp…...

Linux 三十六章

​​​​​​​ &#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要…...

ntsd用法+安装包

ntsd是一个强大的进程终止软件&#xff0c;除了少数系统进程之外一律杀掉 用法 1.ntsd -c q -p 进程的pid 2.ntsd -c q -pn 进程名 记得解压到System32里面 当然&#xff0c;资源管理器的进程是可以杀的所以也可以让电脑黑屏 同样可以让电脑黑屏的还有taskkill /f /im 进程…...

Nacos 微服务管理

Nacos 本教程将为您提供Nacos的基本介绍&#xff0c;并带您完成Nacos的安装、服务注册与发现、配置管理等功能。在这个过程中&#xff0c;您将学到如何使用Nacos进行微服务管理。下方是官方文档&#xff1a; Nacos官方文档 1. Nacos 简介 Nacos&#xff08;Naming and Confi…...

Kubernetes集群上的Etcd备份和恢复

在本教程中&#xff0c;您将学习如何在Kubernetes集群上使用etcd快照进行etcd备份和恢复。 在Kubernetes架构中&#xff0c;etcd是集群的重要组成部分。所有集群对象及其状态都存储在etcd中。为了更好地理解Kubernetes&#xff0c;有几点关于etcd的信息是您需要了解的。 它是…...

创建型模式 (Python版)

单例模式 懒汉式 class SingleTon:# 类属性_obj None # 用来存储对象# 创造对象def __new__(cls, *args, **kwargs):# 如果对象不存在&#xff0c;就创造一个对象if cls._obj is None:cls._obj super().__new__(cls, *args, *kwargs)# 返回对象return cls._objif __name__…...

​​​【收录 Hello 算法】9.4 小结

目录 9.4 小结 1. 重点回顾 2. Q & A 9.4 小结 1. 重点回顾 图由顶点和边组成&#xff0c;可以表示为一组顶点和一组边构成的集合。相较于线性关系&#xff08;链表&#xff09;和分治关系&#xff08;树&#xff09;&#xff0c;网络关系&#xff08;图&am…...

MYSQL数据库基础语法

目录 友情提醒第一章&#xff1a;数据库简述1&#xff09;数据库简述2&#xff09;常见的数据库软件3&#xff09;MySQL数据库安装和连接4&#xff09;SQL语句分类①DDL&#xff08;Data Definition&#xff09;②DML&#xff08;Data Manipulation&#xff09;③DQL&#xff0…...

R实验 参数检验(二)

实验目的&#xff1a;掌握正态分布和二项分布中&#xff0c;功效与样本容量之间的关系&#xff1b;学会利用R软件完成一个正态总体方差和两个正态总体方差比的区间估计和检验。 实验内容&#xff1a; &#xff08;习题5.28&#xff09;一种药物可治疗眼内高压&#xff0c;目的…...

【Linux】进程信号及相关函数/系统调用的简单认识与使用

文章目录 前言一、相关函数/系统调用1. signal2. kill3. abort (库函数)4. raise (库函数)5. alarm 前言 现实生活中, 存在着诸多信号, 比如红绿灯, 上下课铃声…我们在接收到信号时, 就会做出相应的动作. 对于进程也是如此的, 进程也会收到来自 OS 发出的信号, 根据信号的不同…...

Spring (14)什么是Spring Boot

Spring Boot是一个开源的Java基础框架&#xff0c;旨在简化Spring应用的创建和开发过程。Spring Boot通过提供一套默认配置&#xff08;convention over configuration&#xff09;&#xff0c;自动配置和启动器&#xff08;starters&#xff09;来减少开发者的开发工作量和配置…...

区间预测 | Matlab实现CNN-KDE卷积神经网络结合核密度估计多置信区间多变量回归区间预测

区间预测 | Matlab实现CNN-KDE卷积神经网络结合核密度估计多置信区间多变量回归区间预测 目录 区间预测 | Matlab实现CNN-KDE卷积神经网络结合核密度估计多置信区间多变量回归区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CNN-KDE卷积神经网络结合…...

Java集合框架全景解读:从源码到实践精通指南

1. Java集合框架简介 在Java中&#xff0c;集合框架是用于存储和处理数据集合的一组类和接口。它提供了一系列的数据结构&#xff0c;比如列表&#xff08;List&#xff09;、集&#xff08;Set&#xff09;和映射&#xff08;Map&#xff09;。这些数据结构为开发者处理数据提…...

Python | Leetcode Python题解之第107题二叉树的层序遍历II

题目&#xff1a; 题解&#xff1a; class Solution:def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:levelOrder list()if not root:return levelOrderq collections.deque([root])while q:level list()size len(q)for _ in range(size):node q.popl…...

H4vdo 台湾APT-27视频投放工具

地址:https://github.com/MartinxMax/H4vdo 视频 关于 H4vdo RTMP lock 屏播放视频工具&#xff0c;可以向目标发送有效载荷&#xff0c;播放目标的屏幕内容。目标无法曹作计算机 使用方法 安装依赖 根据你的操作系统选择一个安装程序 RTMP 服务端 ./rtsp-simple-server.…...

数据结构(树)

1.树的概念和结构 树&#xff0c;顾名思义&#xff0c;它看起来像一棵树&#xff0c;是由n个结点组成的非线性的数据结构。 下面就是一颗树&#xff1a; 树的一些基本概念&#xff1a; 结点的度&#xff1a;一个结点含有的子树的个数称为该结点的度&#xff1b; 如上图&#…...

1.1 AI技术全景图:从传统ML到大模型

AI技术全景图&#xff1a;从传统ML到大模型本文适合谁&#xff1a;完全没有AI背景的读者。读完这篇&#xff0c;你会知道"AI/机器学习/深度学习/大模型"这几个词是什么关系&#xff0c;以及你将要学的东西在整个AI世界里处于什么位置。AI发展经历了三个时代——本文带…...

项目管理工具怎么选?8款主流产品测评与选型建议

项目管理工具怎么选&#xff1f;真正需要比较的&#xff0c;不只是功能多少&#xff0c;而是它是否适合团队的协作方式、项目复杂度和管理阶段。本文围绕场景匹配、流程灵活性、信息沉淀、管理视图和落地成本&#xff0c;对8款主流项目管理工具做一轮顾问式测评。引言很多企业在…...

基于2026校招数据分析:拥有这几张AI证书的学生,起薪普遍高30%

2026年校招季已近尾声&#xff0c;随着DeepSeek等大模型技术的持续突破与“人工智能”向千行百业的深度渗透&#xff0c;AI人才市场的竞争呈现白热化态势。前程无忧51job发布的《2026届校招市场AI人才需求报告》显示&#xff0c;AI相关岗位校招薪酬中位数已突破2万元/月&#x…...

TVM构建系统详解:CMake与Makefile配置最佳实践

TVM构建系统详解&#xff1a;CMake与Makefile配置最佳实践 引言&#xff1a;TVM构建系统的核心挑战 深度学习编译器TVM&#xff08;Tensor Virtual Machine&#xff09;作为一个跨平台、多后端的开源项目&#xff0c;其构建系统面临着独特的复杂性。开发者需要在不同架构&#…...

JAVA重点基础、进阶知识及易错点总结(1)---数据类型、运算符、流程控制

&#x1f680; Java 巩固进阶 第1天 主题&#xff1a;数据类型、运算符与流程控制 —— 避开那些“隐形”的坑&#x1f4c5; 进度概览&#xff1a;重启Java基础。 &#x1f4a1; 核心价值&#xff1a;很多生产环境的Bug&#xff08;如金额精度丢失、空指针崩溃、逻辑穿透&…...

Android16进阶之MediaPlayer.selectTrack调用流程与实战(二百五十)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》作者 博主新书推荐&#xff1a;《Android系统多媒体进阶实战》&#x1f680; Android Audio工程师专栏地址&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; Android多媒体专栏地址&a…...

日语零基础每天学习笔记【01-10】

第一天 日语五十音&#xff1a;平假名/片假名发音あア いイ うウ えエ おオaかカ きキ くク けケ こコkaさサ しシ すス せセ そソsaたタ ちチ つツ てテ とトtaなナ にニ ぬヌ ねネ のノnaはハ ひヒ ふフ へヘ ほホhaまマ みミ むム めメ もモmaや…...

密码安全必修课:为什么BCrypt比MD5更适合存储用户密码?

密码安全必修课&#xff1a;为什么BCrypt比MD5更适合存储用户密码&#xff1f; 在数字身份成为第二张身份证的时代&#xff0c;密码安全早已不是技术圈的内部话题。去年某社交平台600万用户数据泄露事件中&#xff0c;令人震惊的不是数据被盗本身&#xff0c;而是其中87%的密码…...

FaceFusion项目二次开发踩坑记:深入content_analyser.py,手动修复模型依赖哈希问题

FaceFusion项目二次开发踩坑记&#xff1a;深入content_analyser.py&#xff0c;手动修复模型依赖哈希问题 当你在全新环境中部署经过二次开发的FaceFusion项目时&#xff0c;可能会遇到一个令人头疼的问题——模型文件哈希校验失败。这个问题通常表现为控制台输出类似[FACEFUS…...

华为AR路由器VRRP配置实战:从单点故障到流量黑洞,一个实验全搞定

华为AR路由器VRRP高可用实战&#xff1a;规避单点故障与流量黑洞的深度解析 在现网架构中&#xff0c;网关设备的可靠性直接决定了整个网络的稳定性。想象一下这样的场景&#xff1a;当核心网关突然宕机&#xff0c;整个办公区的网络瞬间瘫痪&#xff0c;业务系统中断&#xff…...