P44,45 属性预处理,执行后游戏效果回调,附录指定区域内修改变量

这节课主要是怎么对Attribute进行在进行到游戏角色前先进行处理,以及游戏效果如何回调

AuraAttributeSet.h

cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

 #include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "GameFramework/Character.h"
#include "AuraAttributeSet.generated.h"


#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
   GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
   GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
   GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
   GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)

/**
 * 
 */
//这里是一个结构体
USTRUCT()
struct  FEffectProperties
{
   GENERATED_BODY()
   FEffectProperties(){}

   FGameplayEffectContextHandle EffectContextHandle;

   UPROPERTY()
   UAbilitySystemComponent* SourceASC = nullptr;

   UPROPERTY()
   AActor* SourceAvatarActor = nullptr;

   UPROPERTY()
   AController* SourceController = nullptr;

   UPROPERTY()
   ACharacter* SourceCharacter = nullptr;

   UPROPERTY()
   UAbilitySystemComponent* TargetASC = nullptr;

   UPROPERTY()
   AActor* TargetAvatarActor = nullptr;

   UPROPERTY()
   AController* TargetController = nullptr;

   UPROPERTY()
   ACharacter* TargetCharacter = nullptr;
};

UCLASS()
class MYGAS_API UAuraAttributeSet : public UAttributeSet
{
     GENERATED_BODY()
 public:
   UAuraAttributeSet();
   virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

   virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;

   virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
   
   //创建AttributeData属性,并且是可以被复制的
   UPROPERTY(BlueprintReadOnly,ReplicatedUsing = OnRep_Health ,Category="Vital Attributes")
   FGameplayAttributeData Health;
   ATTRIBUTE_ACCESSORS(UAuraAttributeSet,Health);
   
   UPROPERTY(BlueprintReadOnly,ReplicatedUsing = OnRep_MaxHealth ,Category="Vital Attributes")
   FGameplayAttributeData MaxHealth;
   ATTRIBUTE_ACCESSORS(UAuraAttributeSet,MaxHealth);

   UPROPERTY(BlueprintReadOnly,ReplicatedUsing = OnRep_Mana ,Category="Vital Attributes")
   FGameplayAttributeData Mana;
   ATTRIBUTE_ACCESSORS(UAuraAttributeSet,Mana);
   
   UPROPERTY(BlueprintReadOnly,ReplicatedUsing = OnRep_MaxMana ,Category="Vital Attributes")
   FGameplayAttributeData MaxMana;
   ATTRIBUTE_ACCESSORS(UAuraAttributeSet,MaxMana);
   
   UFUNCTION()
   void OnRep_Health(const FGameplayAttributeData& OldHealth) const;

   UFUNCTION()
   void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const;

   UFUNCTION()
   void OnRep_Mana(const FGameplayAttributeData& OldMana) const;

   UFUNCTION()
   void OnRep_MaxMana(const FGameplayAttributeData& OldMaxMana) const;

private:
   void SetEffectProperties(const FGameplayEffectModCallbackData& Data , FEffectProperties& Props) const;
};

AuraAttributeSet.cpp

cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.


#include "AbilitySystem/AuraAttributeSet.h"

#include "AbilitySystemBlueprintLibrary.h"
#include "GameplayEffectExtension.h"
#include "GameFramework/Character.h"
#include "GameFramework/Pawn.h"
#include "Net/UnrealNetwork.h"
#include "PlayerController/AuraPlayerController.h"

UAuraAttributeSet::UAuraAttributeSet()
{
   InitHealth(50.f);
   InitMaxHealth(100.f);
   InitMana(25.f);
   InitMaxMana(50.f);
   
}

void UAuraAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
   //用来表示在Actor生命周期内要复制的属性,被创建并且复制的时候在网络上进行同步,确保客户端和服务端状态一致
   Super::GetLifetimeReplicatedProps(OutLifetimeProps);
   //这是一个宏,用来表现属性的复制条件和什么时候调用RepNotify,其中Cond指属性什么时候进行复制,Repnotify是指什么时候调用RepNotify函数,这里是Always,只要服务器接收到属性值就调用复制
   DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet,Health,COND_None,REPNOTIFY_Always);
   
   DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet,MaxHealth,COND_None,REPNOTIFY_Always);
   
// DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet,Mana,COND_None,REPNOTIFY_Always);
   
// DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet,MaxMana,COND_None,REPNOTIFY_Always);
   
}
//数值在应用到角色前进行修改 
void UAuraAttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)
{
   Super::PreAttributeChange(Attribute, NewValue);
   //限制 health和Mana的最低值和最高值
   if(Attribute == GetHealthAttribute())
   {
      NewValue = FMath::Clamp(NewValue,0.f,GetMaxHealth());
   }
   if(Attribute == GetManaAttribute())
   {
      NewValue = FMath::Clamp(NewValue,0.f,GetMaxMana());
   }
}

void UAuraAttributeSet::SetEffectProperties(const FGameplayEffectModCallbackData& Data, FEffectProperties& Props) const
{
   // Source = causer  of the effect , Targetg = Target of the Effect (owner of this AS) 效果的上下文处理,包括来源和目标
   Props.EffectContextHandle = Data.EffectSpec.GetContext();
   // 获取效果的来源能力系统组件
   Props.SourceASC =Props.EffectContextHandle.GetOriginalInstigatorAbilitySystemComponent();
   // 如果有效,则获取来源的相关信息
   if(IsValid(Props.SourceASC) && Props.SourceASC->AbilityActorInfo.IsValid() && Props.SourceASC->AbilityActorInfo->AvatarActor.IsValid())
   {
      Props.SourceAvatarActor = Props.SourceASC->AbilityActorInfo->AvatarActor.Get();
      Props.SourceController = Props.SourceASC->AbilityActorInfo->PlayerController.Get();
      // 如果来源控制器为空且存在角色,则获取角色的控制器
      if(Props.SourceController == nullptr && Props.SourceAvatarActor != nullptr)
      {
         if(const APawn* Pawn = Cast<APawn>(Props.SourceAvatarActor))
         {
            Props.SourceController = Pawn->GetController();
         }
      }
      // 如果存在来源控制器,则尝试将其转换为角色
      if(Props.SourceController)
      {
         Props.SourceCharacter = Cast<ACharacter>(Props.SourceController->GetPawn());
      }
   }
   // 获取目标的相关信息
   if(Data.Target.AbilityActorInfo.IsValid() && Data.Target.AbilityActorInfo->AvatarActor.IsValid())
   {
      Props.TargetAvatarActor = Data.Target.AbilityActorInfo->AvatarActor.Get();
      Props.TargetController = Data.Target.AbilityActorInfo->PlayerController.Get();
      Props.TargetCharacter = Cast<ACharacter>(Props.TargetAvatarActor);
      Props.TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(Props.TargetAvatarActor);
      
   }
   
   //这里是用来Debug对生命值产生的数值
   /*if(Data.EvaluatedData.Attribute == GetHealthAttribute())
   {
      UE_LOG(LogTemp , Warning , TEXT("Health from GetHealth :%f"), GetHealth());
      UE_LOG(LogTemp , Warning , TEXT("Magnitude :%f"), Data.EvaluatedData.Magnitude);
   }*/
}
 
void UAuraAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
   Super::PostGameplayEffectExecute(Data);
   FEffectProperties Props;
   SetEffectProperties(Data,Props);
}

void UAuraAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) const
{
   //这是一个宏,当对象在服务端发生变化的时候可以复制到所有客户端上
   GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet,Health,OldHealth);
}

void UAuraAttributeSet::OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const
{
   GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet,MaxHealth,OldMaxHealth);
}

void UAuraAttributeSet::OnRep_Mana(const FGameplayAttributeData& OldMana) const
{
   GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet,Mana,OldMana);
}

void UAuraAttributeSet::OnRep_MaxMana(const FGameplayAttributeData& OldMaxMana) const
{
   GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet,MaxMana,OldMaxMana);
}


      

附录

Ctrl + h 指定区域内替换关键字

相关推荐
智算菩萨1 小时前
【OpenGL】10 完整游戏开发实战:基于OpenGL的2D/3D游戏框架、物理引擎集成与AI辅助编程指南
人工智能·python·游戏·3d·矩阵·pygame·opengl
风酥糖4 小时前
Godot游戏练习01-第20节-增加亿点点细节
游戏·游戏引擎·godot
聊点儿技术6 小时前
游戏账号盗用频发,IP风险等级评估如何成为第一道防线?
安全·游戏·ip地址·风险评估·账号安全·ip风险等级评估
Swift社区7 小时前
鸿蒙游戏里的 AI Agent 设计
人工智能·游戏·harmonyos
CDN3607 小时前
360CDN 产品实测合集:CDN / 高防 / SDK 游戏盾真实反馈
运维·游戏·网络安全
crazyJialin8 小时前
聊聊一个游戏是怎么做出来的
游戏·cocos2d
呆子也有梦9 小时前
redis 的延时双删、双重检查锁定在游戏服务端的使用(伪代码为C#)
redis·后端·游戏·缓存·c#
IT从业者张某某10 小时前
基于DEVC++实现一个控制台的赛车游戏-01-背景知识
c++·游戏
毕设源码-赖学姐1 天前
【开题答辩全过程】以 基于SSM的游戏商城系统为例,包含答辩的问题和答案
游戏
云边散步1 天前
godot2D游戏教程系列二(23)
笔记·学习·游戏·音视频·游戏开发