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游戏中,都存在一个类别就是属性伤害,比如,在一个游戏里面有一个火属性的技能,它造成的伤害就是火属性类型的,并且它还有可能有附加伤害,比如给予目标一个灼烧效果,每秒造成多少的火属…...

llama3 微调教程之 llama factory 的 安装部署与模型微调过程,模型量化和gguf转换。
本文记录了从环境部署到微调模型、效果测试的全过程,以及遇到几个常见问题的解决办法,亲测可用(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 三十六章
🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C,linux 🔥座右铭:“不要…...
ntsd用法+安装包
ntsd是一个强大的进程终止软件,除了少数系统进程之外一律杀掉 用法 1.ntsd -c q -p 进程的pid 2.ntsd -c q -pn 进程名 记得解压到System32里面 当然,资源管理器的进程是可以杀的所以也可以让电脑黑屏 同样可以让电脑黑屏的还有taskkill /f /im 进程…...

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

Kubernetes集群上的Etcd备份和恢复
在本教程中,您将学习如何在Kubernetes集群上使用etcd快照进行etcd备份和恢复。 在Kubernetes架构中,etcd是集群的重要组成部分。所有集群对象及其状态都存储在etcd中。为了更好地理解Kubernetes,有几点关于etcd的信息是您需要了解的。 它是…...
创建型模式 (Python版)
单例模式 懒汉式 class SingleTon:# 类属性_obj None # 用来存储对象# 创造对象def __new__(cls, *args, **kwargs):# 如果对象不存在,就创造一个对象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. 重点回顾 图由顶点和边组成,可以表示为一组顶点和一组边构成的集合。相较于线性关系(链表)和分治关系(树),网络关系(图&am…...
MYSQL数据库基础语法
目录 友情提醒第一章:数据库简述1)数据库简述2)常见的数据库软件3)MySQL数据库安装和连接4)SQL语句分类①DDL(Data Definition)②DML(Data Manipulation)③DQL࿰…...
R实验 参数检验(二)
实验目的:掌握正态分布和二项分布中,功效与样本容量之间的关系;学会利用R软件完成一个正态总体方差和两个正态总体方差比的区间估计和检验。 实验内容: (习题5.28)一种药物可治疗眼内高压,目的…...

【Linux】进程信号及相关函数/系统调用的简单认识与使用
文章目录 前言一、相关函数/系统调用1. signal2. kill3. abort (库函数)4. raise (库函数)5. alarm 前言 现实生活中, 存在着诸多信号, 比如红绿灯, 上下课铃声…我们在接收到信号时, 就会做出相应的动作. 对于进程也是如此的, 进程也会收到来自 OS 发出的信号, 根据信号的不同…...
Spring (14)什么是Spring Boot
Spring Boot是一个开源的Java基础框架,旨在简化Spring应用的创建和开发过程。Spring Boot通过提供一套默认配置(convention over configuration),自动配置和启动器(starters)来减少开发者的开发工作量和配置…...

区间预测 | Matlab实现CNN-KDE卷积神经网络结合核密度估计多置信区间多变量回归区间预测
区间预测 | Matlab实现CNN-KDE卷积神经网络结合核密度估计多置信区间多变量回归区间预测 目录 区间预测 | Matlab实现CNN-KDE卷积神经网络结合核密度估计多置信区间多变量回归区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CNN-KDE卷积神经网络结合…...
Java集合框架全景解读:从源码到实践精通指南
1. Java集合框架简介 在Java中,集合框架是用于存储和处理数据集合的一组类和接口。它提供了一系列的数据结构,比如列表(List)、集(Set)和映射(Map)。这些数据结构为开发者处理数据提…...

Python | Leetcode Python题解之第107题二叉树的层序遍历II
题目: 题解: 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 屏播放视频工具,可以向目标发送有效载荷,播放目标的屏幕内容。目标无法曹作计算机 使用方法 安装依赖 根据你的操作系统选择一个安装程序 RTMP 服务端 ./rtsp-simple-server.…...

数据结构(树)
1.树的概念和结构 树,顾名思义,它看起来像一棵树,是由n个结点组成的非线性的数据结构。 下面就是一颗树: 树的一些基本概念: 结点的度:一个结点含有的子树的个数称为该结点的度; 如上图&#…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...