75 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			75 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								## 概述
							 | 
						|||
| 
								 | 
							
								在GameplayAbility框架中,UAttributeSet负责管理各种属性。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 定义宏
							 | 
						|||
| 
								 | 
							
								在头文件中添加:
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								// 使用AttributeSet.h的宏
							 | 
						|||
| 
								 | 
							
								#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
							 | 
						|||
| 
								 | 
							
									GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
							 | 
						|||
| 
								 | 
							
									GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
							 | 
						|||
| 
								 | 
							
									GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
							 | 
						|||
| 
								 | 
							
									GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								参考注释可以得知,使用这些宏可以让你少写各个属性的Get、Set、Init函数。如果不使用这个宏你也可以自己实现对应的函数。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								这里用到了Ue4的反射。
							 | 
						|||
| 
								 | 
							
								## 添加属性
							 | 
						|||
| 
								 | 
							
								再以下格式添加属性:
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								UPROPERTY(BlueprintReadOnly, Category = "Health")
							 | 
						|||
| 
								 | 
							
								FGameplayAttributeData Health;
							 | 
						|||
| 
								 | 
							
								ATTRIBUTE_ACCESSORS(URPGAttributeSet, Health)
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								## 重写接口
							 | 
						|||
| 
								 | 
							
								ActionRPG案例中重写了PreAttributeChange与PostGameplayEffectExecute接口。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								前者会在属性被修改时调用,在案例中是为了在血量或魔法上限发生变动时,按比例调整当前血量或者魔法值。后者与GameplayEffect有关,等到编写完GameplayEffect时,再来编写。
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								void URPGAttributeSet::PreAttributeChange(const FGameplayAttribute & Attribute, float & NewValue)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									Super::PreAttributeChange(Attribute, NewValue);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									if (Attribute == GetMaxHealthAttribute())
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										AdjustAttributeForMaxChange(Health, MaxHealth, NewValue, GetHealthAttribute());
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									else if (Attribute == GetMaxManaAttribute())
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										AdjustAttributeForMaxChange(Mana, MaxMana, NewValue, GetManaAttribute());
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								void URPGAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData & Data)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									Super::PostGameplayEffectExecute(Data);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								void URPGAttributeSet::AdjustAttributeForMaxChange(FGameplayAttributeData& AffectedAttribute, const FGameplayAttributeData& MaxAttribute, float NewMaxValue, const FGameplayAttribute& AffectedAttributeProperty)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
							 | 
						|||
| 
								 | 
							
									const float CurrentMaxValue = MaxAttribute.GetCurrentValue();
							 | 
						|||
| 
								 | 
							
									if (!FMath::IsNearlyEqual(CurrentMaxValue, NewMaxValue) && AbilityComp)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
										// Change current value to maintain the current Val / Max percent
							 | 
						|||
| 
								 | 
							
										const float CurrentValue = AffectedAttribute.GetCurrentValue();
							 | 
						|||
| 
								 | 
							
										float NewDelta = (CurrentMaxValue > 0.f) ? (CurrentValue * NewMaxValue / CurrentMaxValue) - CurrentValue : NewMaxValue;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
										AbilityComp->ApplyModToAttributeUnsafe(AffectedAttributeProperty, EGameplayModOp::Additive, NewDelta);
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 个人的使用方案
							 | 
						|||
| 
								 | 
							
								定义URPGAttributeSet作为基础属性集,里面定义通用属性。之后又定义URPGCharacterAttributeSet作为角色专用的属性集。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								之后在角色类中的构造函数中挂载URPGAttributeSet对象。
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								UPROPERTY()
							 | 
						|||
| 
								 | 
							
								URPGAttributeSet* AttributeSet;
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								AttributeSet = CreateDefaultSubobject<URPGAttributeSet>(TEXT("AttributeSet"));
							 | 
						|||
| 
								 | 
							
								```
							 |