受击反馈HitReact、死亡效果Death Dissolve、Floating伤害值Text(末尾附 客户端RPC )

受击反馈HitReact

设置角色受击标签 

(GameplayTag基本了解待补充)

角色监听标签并设置移动速度

创建一个受击技能,并应用GE

实现设置角色的受击蒙太奇动画

        实现角色受击时播放蒙太奇动画,为了保证通用性,将其设置为一个函数,并设置到战斗接口中,这样只需要在战斗接口中获取对应角色的蒙太奇即可。(每个角色的受击动画不一定一样)

UCLASS()
class AURA_API AAuraCharacterBase : public ACharacter, public IAbilitySystemInterface, public ICombatInterface
{GENERATED_BODY()public://HitReactvirtual UAnimMontage* GetHitReactMontage_Implementation() override;private:UPROPERTY(EditAnywhere, Category = "Combat")TObjectPtr<UAnimMontage> HitReactMontage;
};UAnimMontage* AAuraCharacterBase::GetHitReactMontage_Implementation()
{return HitReactMontage;
}

别忘了设置对应的HitReact_AM

激活受击技能

在CharacterClassInfo.h里增加一个参数,用于设置创建敌人时所拥有的初始技能

在函数技能库里新增一个函数用于初始化角色技能

UCLASS()
class AURA_API UMyASBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{GENERATED_BODY()
public://初始化角色的技能UFUNCTION(BlueprintCallable, Category="MyBlueprintFunctionLibrary|CharacterClassDefaults")static void GiveStartupAbilities(const UObject* WorldContextObject, UAbilitySystemComponent* ASC);};void UMyASBlueprintFunctionLibrary::GiveStartupAbilities(const UObject* WorldContextObject, UAbilitySystemComponent* ASC)
{//获取到当前关卡的GameMode实例const AAuraGameModeBase* GameMode = Cast<AAuraGameModeBase>(UGameplayStatics::GetGameMode(WorldContextObject));if(GameMode == nullptr) return;//从实例获取到关卡角色的配置UCharacterClassInfo* CharacterClassInfo = GameMode->CharacterClassInfo;//遍历角色拥有的技能数组for(const TSubclassOf<UGameplayAbility> AbilityClass : CharacterClassInfo->CommonAbilities){FGameplayAbilitySpec AbilitySpec = FGameplayAbilitySpec(AbilityClass, 1); //创建技能实例ASC->GiveAbility(AbilitySpec); //只应用不激活}
}

在敌人基类里,开始事件时,我们调用函数库的初始化技能函数,将技能应用到角色身上

void AAuraEnemy::BeginPlay()
{Super::BeginPlay();InitAbilityActorInfo();//初始化角色的技能UMyASBlueprintFunctionLibrary::GiveStartupAbilities(this, AbilitySystemComponent);...
}

在PostGameplayEffectExecute函数里,之前设置血量下面有判断,我们在角色没有被击杀时,让其触发受击技能。 

void UAuraAttributeSet::PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data)
{...//查看IncomingDamage修改的是否为元属性if(Data.EvaluatedData.Attribute == GetIncomingDamageAttribute()){//获取到元属性的值备用,并将属性集上的值设置为0,等待下一次设置。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时,角色将会死亡 致命的(Fatal)if(!bFatal) //在角色没有被击杀时,让其触发受击技能。{FGameplayTagContainer TagContainer;TagContainer.AddTag(FMyGameplayTags::Get().Effects_HitReact); //添个眼 这里原本是Effects.HitReact 对应GA一样  我是修改了Props.TargetASC->TryActivateAbilitiesByTag(TagContainer); //根据tag标签激活技能}}}

 接下来是蓝图中的设置(已做修改)

我们将使用标签激活技能,所以还需要将受击标签设置给技能

我们不需要在每次激活时创建一个新的实例,只需要一个角色生成一个实例重复利用即可。

        由于它一个角色对应一个单例,每次触发都是相同的实例,所以,我们需要在其播放完成后,将其结束,才可以重新触发,然后,在敌人的受击动画播放完成后,我们需要将敌人身上的受击标签清楚(如果GE添加的,只需要将对应的GE清除,标签也会随着清除)并结束技能。 

死亡效果Death/Dissolve

        我们实现了敌人受到攻击后会播放受击动画,并且还给角色设置了受击标签。并在角色受击时,在角色身上挂上受击标签,在c++里,如果挂载了此标签,速度将降为0 。
受击有了,接下来我们将实现角色的死亡逻辑,角色血量为0或者小于0时,我们将触发它的死亡功能

实现死亡

在战斗接口类里增加一个纯虚函数无法创建函数的实现,必须在子类里面去覆写它。

	virtual void Die() = 0;

在角色基类里面覆写

virtual void Die() override;

接着我们增加一个在每个客户端上执行的函数,被Die函数调用。
NetMulticast设置后,这个函数被调用时,将在服务器执行,然后复制到每个客户端。和它对应的还有(Server:只在服务器运行,Client:只在调用此函数的客户端运行)这种情况的函数实现需要在后面加上_Implementation
Reliable: 这是一个传输属性,表示该函数的数据应该以可靠的方式发送。

	UFUNCTION(NetMulticast, Reliable)virtual void MulticastHandleDeath();
void AAuraCharacterBase::Die()
{//将武器从角色身上分离(Detach)Weapon->DetachFromComponent(FDetachmentTransformRules(EDetachmentRule::KeepWorld, true));MulticastHandleDeath(); //NetMulticast在服务器执行,然后复制到每个客户端()
}void AAuraCharacterBase::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);
}

在敌人基类里面也覆盖Die函数,并在死亡时设置它的清除时间

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Combat")float LifeSpan = 5.f; //设置死亡后的存在时间void AAuraEnemy::Die()
{SetLifeSpan(LifeSpan); //在Enemy死亡后尸体会存在五秒 对象不再需要时会自动销毁Super::Die();
}

接下来在AttributeSet的PostGameplayEffectExecute函数里,增加Die函数调用的逻辑处理,我们在死亡时调用即可 

void UAuraAttributeSet::PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data)
{。。。//查看IncomingDamage修改的是否为元属性if(Data.EvaluatedData.Attribute == GetIncomingDamageAttribute()){//获取到元属性的值备用,并将属性集上的值设置为0,等待下一次设置。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时,角色将会死亡 致命的(Fatal)if(bFatal){//调用死亡函数ICombatInterface* CombatInterface = Cast<ICombatInterface>(Props.TargetAvatarActor);if(CombatInterface){CombatInterface->Die();}}else{在角色没有被击杀时,让其触发受击技能。FGameplayTagContainer TagContainer;TagContainer.AddTag(FMyGameplayTags::Get().Abilities_HitReact);  //添个眼 这里原本是Effects.HitReact 对应GA一样  我是修改了Props.TargetASC->TryActivateAbilitiesByTag(TagContainer); //根据tag标签激活技能}}}

测试效果

溶解材质(目前渲染方面不做了解)

小怪死亡定时直接清除掉,显得太突兀,大部分游戏中的做法就是使用溶解效果来实现它的缓慢消失的效果。

实现溶解效果

        实现从普通材质切换MI到溶解材质,并实现通过程序修改Dissolve溶解的标量Scalar Parameter参数数值。(步骤

        增加两个变量,用于设置角色和武器的溶解材质

        增加一个溶解函数,在角色死亡时调用

        溶解是需要一个时间过程,所以可以在蓝图里面实现时间轴,所以增加一个蓝图可实现函数,这个函数在代码里调用,在蓝图实现。

// YanWei.UCLASS()
class AURA_API AAuraCharacterBase : public ACharacter, public IAbilitySystemInterface, public ICombatInterface
{GENERATED_BODY()public://--ICombatInterfacevirtual UAnimMontage* GetHitReactMontage_Implementation() override;//HitReactvirtual void Die() override; //Death  OnServer 服务器端 UFUNCTION(NetMulticast, Reliable) //NetMulticast:在服务器执行,然后复制到每个客户端virtual void MulticastHandleDeath();protected://--Dissolve Effect 实现思路:是将avatar和weapon的材质叫换成下面的//溶解函数void Dissolve(); //蓝图可实现事件UFUNCTION(BlueprintImplementableEvent)void StartDissolveTimeline(const TArray<UMaterialInstanceDynamic*>& DynamicMaterialInstance); //接受材质实例dyn 数组用于存储材质sUPROPERTY(EditAnywhere,BlueprintReadOnly)TObjectPtr<UMaterialInstance> DissolveMaterialInstance; //对应的材质实例UPROPERTY(EditAnywhere,BlueprintReadOnly)TObjectPtr<UMaterialInstance> WeaponDissolveMaterialInstance;//};//cppvoid AAuraCharacterBase::Dissolve()
{TArray<UMaterialInstanceDynamic*> DynMatArray;if (DissolveMaterialInstance){UMaterialInstanceDynamic* DynamicMatInst = UMaterialInstanceDynamic::Create(DissolveMaterialInstance, this);GetMesh()->SetMaterial(0, DynamicMatInst);DynMatArray.Add(DynamicMatInst);}if (WeaponDissolveMaterialInstance){UMaterialInstanceDynamic* DynamicMatInst = UMaterialInstanceDynamic::Create(WeaponDissolveMaterialInstance, this);Weapon->SetMaterial(0, DynamicMatInst);DynMatArray.Add(DynamicMatInst);}StartDissolveTimeline(DynMatArray);
}void AAuraCharacterBase::Die()
{//将武器从角色身上分离(Detach)Weapon->DetachFromComponent(FDetachmentTransformRules(EDetachmentRule::KeepWorld, true));MulticastHandleDeath(); //NetMulticast在服务器执行,然后复制到每个客户端()
}void AAuraCharacterBase::MulticastHandleDeath_Implementation()
{...//设置角色溶解Dissolve();
}

打开UE,在敌人基类里面覆写StartDissolveTimeline   (增加线结点<Add Reroute>)


创建一个时间轴 Timeline 并点击它 

 

 Set Scalar Parameter Value

效果图

伤害值浮动FloatingText

        实现技能或者攻击对敌人造成的伤害数值,并直观的显示出来。接下来,还要实现一个用户控件,来设置伤害数值的UI表现。并且还需要一个用户控件的组件来修改伤害UI显示的数值。在创建完成这些以后,我们还需要实现从AttributeSet里面实现在目标位置(也就是受到伤害的角色位置)创建组件,并实现在每个客户端上面显示数值。

创建Damage用户控件

新建一个控件蓝图,这里不需要其它脚本直接基于UserWidget创建即可。我们将其命名为WBP_DamageText

在控件里面增加一个覆层,覆层下面添加一个文本显示文字

在控件尺寸这里,我们使用自定义,来设置一个固定的尺寸,这样它的尺寸不会乱动,不会在更新时频繁修改尺寸影响性能。

然后设置文本的样式,并将其设置为变量,方便后期修改其显示的内容

创建伤害文字动画 (视觉反馈很重要!)

动画创建完成后,在事件构造时调用动画播放

创建用户控件组件

用户控件创建完成,我们还需要创建用户控件组件,用于实现用户控件的实例化并播放动画。
所以,我们接下来要创建一个用户组件的控件,创建基于最基本的组件即可,我们不需要从控制器获取内容,只需要一个设置显示数字的方法即可。命名为DamageTextComponent

增加一个函数,设置伤害的数值,可以在蓝图内实现此函数,并且可以在蓝图内调用

基于此类创建一个蓝图类,命名为BP_DamageTextComponent

现在这个蓝图相当于一个未挂载在对象上面的组件类,但是我们可以设置它的默认参数。我们将空间修改为屏幕空间,并将创建的用户控件设置上去

在蓝图内,我们实现SetDamageText,将设置的类型转换为我们创建的用户组件类型,调用它的更新数字方法,然后在延迟一秒钟(动画播放一秒钟)后,将自身销毁,组件也会跟随销毁。

其中 UpdateDamageText   鼠标处设0是为了只显示整数部分

调用实现伤害显示

现在,我们有了显示伤害数值的用户控件和组件,接下来就要考虑实现如何调用并显示对应的内容。
现在有个问题,就是我们是通过在AttributeSet里面通过元属性获取到当前的伤害的,它是在服务器上运行的,因此,我们要实现在AttributeSet里面去调用函数生成,并且,还需要获取到玩家控制器,因为你需要将数值显示给玩家查看得,所以,我们将数值在玩家控制器里面实现在每个客户端上面调用是一个很好的选择。
所以,我们打开玩家控制器的基类,在里面增加一个函数,用于复制到每个客户端并且只会在客户端执行所以我们设置了Client (只在客户端执行)
函数内部实现在目标角色身上显示伤害数字

(制作一个客户端RPC函数,如果在服务端调用它,它将在服务端执行,如果玩家控制器是本地Local的话;但是如果玩家控制器是Remote远程的话,这个函数将被执行在remote远程的客户端)

// YanWei.class UDamageTextComponent;/***  */
UCLASS()
class AURA_API AAuraPlayerController : public APlayerController
{GENERATED_BODY()
public:AAuraPlayerController();virtual void PlayerTick(float DeltaTime) override;//客户端RPC函数UFUNCTION(Client, Reliable)void ShowDamageNumber(float DamageAmount, ACharacter* TargetCharacter); //在每个客户端显示伤害数值private:。。。	//DamageText  创建一个用于设置显示伤害数值的组件类,后续可以使用它去实例化多个实例,显示多个伤害数值UPROPERTY(EditDefaultsOnly)TSubclassOf<UDamageTextComponent> DamageTextComponentClass;};// 客户端的具体实现
void AAuraPlayerController::ShowDamageNumber_Implementation(float DamageAmount,ACharacter* TargetCharacter)
{if(IsValid(TargetCharacter) && DamageTextComponentClass){//在内部实例化组件,并注册,在实例化时,第一个参数相当于作为此组件的父类,当PlayerController被销毁时,它也会被销毁。UDamageTextComponent* DamageText = NewObject<UDamageTextComponent>(TargetCharacter, DamageTextComponentClass);DamageText->RegisterComponent(); //动态创建的组件需要调用注册DamageText->AttachToComponent(TargetCharacter->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform); //先附加到角色身上,使用角色位置DamageText->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform); //然后从角色身上分离,保证在一个位置播放完成动画DamageText->SetDamageText(DamageAmount); //设置显示的伤害数字}
}// YanWei./***  */
UCLASS()
class AURA_API UAuraAttributeSet : public UAttributeSet
{GENERATED_BODY()
protected://用于服务器端调用客户端RPC函数,在客户端执行static void ShowFloatingText(const FEffectProperties& Props, const float Damage);
};// 服务器调用客户端函数的实现
void UAuraAttributeSet::ShowFloatingText(const FEffectProperties& Props, const float Damage)
{//调用显示伤害数字if(Props.SourceCharacter != Props.TargetCharacter){if(AAuraPlayerController* PC = Cast<AAuraPlayerController>(UGameplayStatics::GetPlayerController(Props.SourceCharacter, 0))){//调用客户端RPC函数PC->ShowDamageNumber(Damage, Props.TargetCharacter); //调用显示伤害数字}}
}void UAuraAttributeSet::PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data)
{。。。if(LocalIncomingDamage > 0.f)//伤害传入的时机{。。。//TODO::设置显示float伤害值的区域ShowFloatingText(Props, LocalIncomingDamage);// 服务端请求客户端执行}}

 在BP_Controller控制器中设置bpCompDamageText

测试结果

每个客户端只能看到自己所造成的浮动伤害值,其他客户端看不到别的客户端(也包括监听服务器端)造成浮动伤害值,而(监听)服务端可以看到所有的浮动伤害值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/10389.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue+Echarts 实现青岛自定义样式地图

一、效果 二、代码 <template><div class"chart-box"><chart ref"chartQingdao" style"width: 100%; height: 100%;" :options"options" autoresize></chart></div> </template> <script> …

线段树(Segment Tree)和树状数组

线段树&#xff08;Segment Tree&#xff09;和树状数组 线段树的实现链式&#xff1a;数组实现 解题思路树状数组 线段树是 二叉树结构 的衍生&#xff0c;用于高效解决区间查询和动态修改的问题&#xff0c;其中区间查询的时间复杂度为 O(logN)&#xff0c;动态修改单个元素的…

计算机网络 (62)移动通信的展望

一、技术发展趋势 6G技术的崛起 内生智能&#xff1a;6G将强调自适应网络架构&#xff0c;通过AI驱动的智能算法提升通信能力。例如&#xff0c;基于生成式AI的6G内生智能架构将成为重要研究方向&#xff0c;实现低延迟、高效率的智能通信。信息编码与调制技术&#xff1a;新型…

数据结构 前缀中缀后缀

目录 前言 一&#xff0c;前缀中缀后缀的基本概念 二&#xff0c;前缀与后缀表达式 三&#xff0c;使用栈实现后缀 四&#xff0c;由中缀到后缀 总结 前言 这里学习前缀中缀后缀为我们学习树和图做准备&#xff0c;这个主题主要是对于算术和逻辑表达式求值&#xff0c;这…

音视频多媒体编解码器基础-codec

如果要从事编解码多媒体的工作&#xff0c;需要准备哪些更为基础的内容&#xff0c;这里帮你总结完。 因为数据类型不同所以编解码算法不同&#xff0c;分为图像、视频和音频三大类&#xff1b;因为流程不同&#xff0c;可以分为编码和解码两部分&#xff1b;因为编码器实现不…

AI大模型开发原理篇-1:语言模型雏形之N-Gram模型

N-Gram模型概念 N-Gram模型是一种基于统计的语言模型&#xff0c;用于预测文本中某个词语的出现概率。它通过分析一个词语序列中前面N-1个词的出现频率来预测下一个词的出现。具体来说&#xff0c;N-Gram模型通过将文本切分为长度为N的词序列来进行建模。 注意&#xff1a;这…

Windows系统本地部署deepseek 更改目录

本地部署deepseek 无论是mac还是windows系统本地部署deepseek或者其他模型的命令和步骤是一样的。 可以看: 本地部署deepsek 无论是ollama还是部署LLM时候都默认是系统磁盘&#xff0c;对于Windows系统&#xff0c;我们一般不把应用放到系统盘&#xff08;C:&#xff09;而是…

知识库管理如何推动企业数字化转型与创新发展的深层次探索

内容概要 在当今数字化转型的大背景下&#xff0c;知识库管理日益显现出其作为企业创新发展的核心驱动力的潜力。这种管理方式不仅仅是对信息的存储与检索&#xff0c;更是一种赋能&#xff0c;以提升决策效率和员工创造力。企业能够通过系统地整合和管理各类知识资源&#xf…

商品列表及商品详情展示

前言 本文将展示一段结合 HTML、CSS 和 JavaScript 的代码&#xff0c;实现了一个简单的商品展示页面及商品详情&#xff0c;涵盖数据获取、渲染、搜索及排序等功能。 效果展示 点击不同的商品会展示对应的商品详情。 代码部分 代码总体实现 <!DOCTYPE html> <htm…

论文阅读:Realistic Noise Synthesis with Diffusion Models

这篇文章是 2025 AAAI 的一篇工作&#xff0c;主要介绍的是用扩散模型实现对真实噪声的仿真模拟 Abstract 深度去噪模型需要大量来自现实世界的训练数据&#xff0c;而获取这些数据颇具挑战性。当前的噪声合成技术难以准确模拟复杂的噪声分布。我们提出一种新颖的逼真噪声合成…

【汽车电子架构】AutoSAR从放弃到入门专栏导读

本文是汽车电子架构&#xff1a;AutoSAR从放弃到入门专栏的导读篇。文章延续专栏文章的一贯作风&#xff0c;从概念与定义入手&#xff0c;希望读者能对AutoSAR架构有一个整体的认识&#xff0c;然后对专栏涉及的文章进行分类与链接。本文首先从AutoSAR汽车软件架构的概念&…

毕业设计--具有车流量检测功能的智能交通灯设计

摘要&#xff1a; 随着21世纪机动车保有量的持续增加&#xff0c;城市交通拥堵已成为一个日益严重的问题。传统的固定绿灯时长方案导致了大量的时间浪费和交通拥堵。为解决这一问题&#xff0c;本文设计了一款智能交通灯系统&#xff0c;利用车流量检测功能和先进的算法实现了…

FPGA|使用quartus II通过AS下载POF固件

1、将开发板设置到AS下载挡位&#xff0c;或者把下载线插入到AS端口 2、打开quartus II&#xff0c;选择Tools→Programmer→ Mode选择Active Serial Programming 3、点击左侧Add file…&#xff0c;选择 .pof 文件 →start 4、勾选program和verify&#xff08;可选&#xff0…

适合超多氛围灯节点应用的新选择

文章目录 1.前言2.芯片简介2.1 高动态RGB照明2.2 灵活的通信模式2.3 精确的颜色控制2.4 高性能与可靠性2.5 易于集成与控制 3.硬件介绍3.1 方案框图3.2 通信模式3.3 器件选型 4.基础操作4.1 基础操作示例4.2 状态机4.3 启动行为4.4 诊断 5 颜色控制和温度稳定化5.1 颜色控制5.2…

MATLAB-Simulink并行仿真示例

一、概述 在进行simulink仿真的过程中常常遇到CPU利用率较低&#xff0c;仿真缓慢的情况&#xff0c;可以借助并行仿真改善这些问题&#xff0c;其核心思想是将参数扫描、蒙特卡洛分析或多工况验证等任务拆分成多个子任务&#xff0c;利用多核CPU或计算集群的并行计算能力&…

运算符重载(输出运算符<<) c++

我们来看下面这个Bug 报错1&#xff1a;打印整形&#xff08;int&#xff09;可以直接打印&#xff0c;打印字符&#xff08;char&#xff09;也可以直接打印&#xff0c;那是因为本身就已经给我们的内置类型准备好了一个输出运算符&#xff0c;可以直接用&#xff0c;但是我们…

【C++】类和对象(5)

目录 一、构造函数补充1、初始化列表 二、类型转换三、static成员四、友元1、友元函数2、友元类 五、内部类六、匿名对象 一、构造函数补充 对于之前讲解的构造函数&#xff0c;还有一些更深层次的内容要进行补充&#xff0c;接下来进行补充内容的讲解。 1、初始化列表 在我…

反向代理模块b

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当于…

Python - Quantstats量化投资策略绩效统计包 - 详解

使用Quantstats包做量化投资绩效统计的时候因为Pandas、Quantstats版本不匹配踩了一些坑&#xff1b;另外&#xff0c;Quantstats中的绩效统计指标非常全面&#xff0c;因此详细记录一下BUG修复方法、使用说明以及部分指标的内涵示意。 一、Quantstats安装及版本匹配问题 可以…

C#,入门教程(13)——字符(char)及字符串(string)的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(12)——数组及数组使用的基础知识https://blog.csdn.net/beijinghorn/article/details/123918227 字符串的使用与操作是必需掌握得滚瓜烂熟的编程技能之一&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; C#语言实…