UE学习日志#6 GAS--ACS源码简要分析4 AS相关

 还是老规矩只贴我不太理解或者重要的,一些简单的GetSet就不贴了

1 AddSpawnedAttribute

这里按顺序放几个模板的定义,关键还是看AddSpawnedAttribute

	/** Finds existing AttributeSet */
	template <class T >
	const T*	GetSet() const
	{
		return (T*)GetAttributeSubobject(T::StaticClass());
	}

	/** Finds existing AttributeSet. Asserts if it isn't there. */
	template <class T >
	const T*	GetSetChecked() const
	{
		return (T*)GetAttributeSubobjectChecked(T::StaticClass());
	}

	/** Adds a new AttributeSet (initialized to default values) */
	template <class T >
	const T*  AddSet()
	{
		return (T*)GetOrCreateAttributeSubobject(T::StaticClass());
	}

	/** 
	 * Manually add a new attribute set that is a subobject of this ability system component.
	 * All subobjects of this component are automatically added during initialization.
	 */
	template <class T>
	const T* AddAttributeSetSubobject(T* Subobject)
	{
		AddSpawnedAttribute(Subobject);
		return Subobject;
	}

下边是具体的AddSpawnedAttribute的实现:

如果需要复制就加入ReplicatedSubObject里,然后直接Add到SpawnedAttributes里,最后做一下标记

void UAbilitySystemComponent::AddSpawnedAttribute(UAttributeSet* Attribute)
{
	if (!IsValid(Attribute))
	{
		return;
	}

	if (SpawnedAttributes.Find(Attribute) == INDEX_NONE)
	{
		if (IsUsingRegisteredSubObjectList() && IsReadyForReplication())
		{
			AddReplicatedSubObject(Attribute);
		}

		SpawnedAttributes.Add(Attribute);
		SetSpawnedAttributesListDirty();
	}
}

这里贴一下SpawnedAttributes的声明:

private:

	/** List of attribute sets */
	UPROPERTY(Replicated, ReplicatedUsing = OnRep_SpawnedAttributes, Transient)
	TArray<TObjectPtr<UAttributeSet>>	SpawnedAttributes;

2 InitStats

这俩还是比较重要的函数,就是用来实现用DataTable初始化attributes的

	/** Initializes starting attributes from a data table. Not well supported, a gameplay effect with curve table references may be a better solution */
	const UAttributeSet* InitStats(TSubclassOf<class UAttributeSet> Attributes, const UDataTable* DataTable);

	UFUNCTION(BlueprintCallable, Category="Skills", meta=(DisplayName="InitStats", ScriptName="InitStats"))
	void K2_InitStats(TSubclassOf<class UAttributeSet> Attributes, const UDataTable* DataTable);

核心InitStats:

其实还没到关键,就是调用了AS的InitFromMetaDataTable

const UAttributeSet* UAbilitySystemComponent::InitStats(TSubclassOf<class UAttributeSet> Attributes, const UDataTable* DataTable)
{
	const UAttributeSet* AttributeObj = nullptr;
	if (Attributes)
	{
		AttributeObj = GetOrCreateAttributeSubobject(Attributes);
		if (AttributeObj && DataTable)
		{
			// This const_cast is OK - this is one of the few places we want to directly modify our AttributeSet properties rather
			// than go through a gameplay effect
			const_cast<UAttributeSet*>(AttributeObj)->InitFromMetaDataTable(DataTable);
		}
	}
	return AttributeObj;
}

 所以我们再去看InitFromMetaDataTable:

1.先看这个循环体,我去查了一下,大概是一个迭代器,遍历这个类中的所有属性(在UE反射系统中的)

for( TFieldIterator<FProperty> It(GetClass(), EFieldIteratorFlags::IncludeSuper) ; It ; ++It )

2.循环内的前半部分:

这里的FNumericProperty是FProperty的子类,代表具体数值类型的

然后就是UE中读取DataTable的流程,从这里的代码能看出来MetaData里只有BaseValue有用

		FProperty* Property = *It;
		FNumericProperty *NumericProperty = CastField<FNumericProperty>(Property);
		if (NumericProperty)
		{
			FString RowNameStr = FString::Printf(TEXT("%s.%s"), *Property->GetOwnerVariant().GetName(), *Property->GetName());
		
			FAttributeMetaData * MetaData = DataTable->FindRow<FAttributeMetaData>(FName(*RowNameStr), Context, false);
			if (MetaData)
			{
				void *Data = NumericProperty->ContainerPtrToValuePtr<void>(this);
				NumericProperty->SetFloatingPointPropertyValue(Data, MetaData->BaseValue);
			}
		}

3.循环体后半部分:

如果是AttributeDataProperty,最后Set的是BaseValue和CurrentValue,值都是数据表里的BaseValue(这么看我之前写的SetBaseValue再SetCurrentValue好像没啥问题)

else if (FGameplayAttribute::IsGameplayAttributeDataProperty(Property))
		{
			FString RowNameStr = FString::Printf(TEXT("%s.%s"), *Property->GetOwnerVariant().GetName(), *Property->GetName());

			FAttributeMetaData * MetaData = DataTable->FindRow<FAttributeMetaData>(FName(*RowNameStr), Context, false);
			if (MetaData)
			{
				FStructProperty* StructProperty = CastField<FStructProperty>(Property);
				check(StructProperty);
				FGameplayAttributeData* DataPtr = StructProperty->ContainerPtrToValuePtr<FGameplayAttributeData>(this);
				check(DataPtr);
				DataPtr->SetBaseValue(MetaData->BaseValue);
				DataPtr->SetCurrentValue(MetaData->BaseValue);
			}
		}

3 小结

        今天这部分说实话都没啥要注意的(我觉得),为了证明我不是真的短,下边把我今天看完的相关函数全部贴在这,具体实现基本上都是见名知意的,不太懂得看看实现和注释也懂了,基本上都是一些GetSet和标准操作的工具函数

bool HasAttributeSetForAttribute(FGameplayAttribute Attribute) const;

	
const UAttributeSet* InitStats(TSubclassOf<class UAttributeSet> Attributes, const UDataTable* DataTable);

UFUNCTION(BlueprintCallable, Category="Skills", meta=(DisplayName="InitStats", ScriptName="InitStats"))
void K2_InitStats(TSubclassOf<class UAttributeSet> Attributes, const UDataTable* DataTable);
		
	
UFUNCTION(BlueprintPure, Category="Gameplay Attributes")
void GetAllAttributes(TArray<FGameplayAttribute>& OutAttributes);

	
UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Gameplay Attributes", meta=(DeterminesOutputType = AttributeSetClass))
const UAttributeSet* GetAttributeSet(TSubclassOf<UAttributeSet> AttributeSetClass) const;

	
UFUNCTION(BlueprintPure, Category = "Gameplay Attributes")
float GetGameplayAttributeValue(FGameplayAttribute Attribute, bool& bFound) const;

UPROPERTY(EditAnywhere, Category="AttributeTest")
TArray<FAttributeDefaults>	DefaultStartingData;

	
void SetSpawnedAttributes(const TArray<UAttributeSet*>& NewAttributeSet);

UE_DEPRECATED(5.1, "This function will be made private. Use Add/Remove SpawnedAttributes instead")
TArray<TObjectPtr<UAttributeSet>>& GetSpawnedAttributes_Mutable();

const TArray<UAttributeSet*>& GetSpawnedAttributes() const;

	
void AddSpawnedAttribute(UAttributeSet* Attribute);

	
void RemoveSpawnedAttribute(UAttributeSet* Attribute);

	
void RemoveAllSpawnedAttributes();


	
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Skills")
FName AffectedAnimInstanceTag; 


	
void SetNumericAttributeBase(const FGameplayAttribute &Attribute, float NewBaseValue);

	
float GetNumericAttributeBase(const FGameplayAttribute &Attribute) const;

	
void ApplyModToAttribute(const FGameplayAttribute &Attribute, TEnumAsByte<EGameplayModOp::Type> ModifierOp, float ModifierMagnitude);

	
void ApplyModToAttributeUnsafe(const FGameplayAttribute &Attribute, TEnumAsByte<EGameplayModOp::Type> ModifierOp, float ModifierMagnitude);

	
float GetNumericAttribute(const FGameplayAttribute &Attribute) const;
float GetNumericAttributeChecked(const FGameplayAttribute &Attribute) const;

	
float GetFilteredAttributeValue(const FGameplayAttribute& Attribute, const FGameplayTagRequirements& SourceTags, const FGameplayTagContainer& TargetTags, const TArray<FActiveGameplayEffectHandle>& HandlesToIgnore = TArray<FActiveGameplayEffectHandle>());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值