这个翻译还是比较准确的(我觉得),跟前面的取消同理,而且本类的调用都在写在了同一个函数里,就是前边的那个ApplyAbilityBlockAndCancelTags,还有一个尖锐的问题:我自己阻塞自己会怎么样,哎这个问题还得看调用的流程,留个坑之后研究运行流程会补。
定义:
/** Abilities with these tags are blocked while this ability is active */
UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="AbilityTagCategory"))
FGameplayTagContainer BlockAbilitiesWithTag;
喷不了这个翻译是真人机,总结来说就是给激活这个能力的ASC添加的标签,看这两行包懂的:
//UGameplayAbility::PreActivate中
UAbilitySystemComponent* Comp = ActorInfo->AbilitySystemComponent.Get();
Comp->AddLooseGameplayTags(ActivationOwnedTags);
当然在EndAbility里会Remove掉的(这个小点我一直是猜的,我才不会说我是打印标签知道的)
激活者需要有所有的ActivationRequiredTags才能激活这个能力
定义:
/** This ability can only be activated if the activating actor/component has all of these tags */
UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="OwnedTagsCategory"))
FGameplayTagContainer ActivationRequiredTags;
这个调用的位置也是老朋友了,之前也出现过
//UGameplayAbility::DoesAbilitySatisfyTagRequirements
CheckForRequired(AbilitySystemComponent.GetOwnedGameplayTags(), ActivationRequiredTags);
这里简单看下CheckForRequired:
// Define a common lambda to check for missing required tags
bool bMissing = false;
auto CheckForRequired = [&](const FGameplayTagContainer& TagsToCheck, const FGameplayTagContainer& RequiredTags)
{
// Do we have no requirements, or have met all requirements? Then nothing's missing
if (RequiredTags.IsEmpty() || TagsToCheck.HasAll(RequiredTags))
{
return;
}
//如果没有需要的标签,直接return
//如果拥有所有需要的标签也return
if (OptionalRelevantTags)
{
// Ensure the global missing tag is only added once
//确保只添加一次
if (!bMissing)
{
UAbilitySystemGlobals& AbilitySystemGlobals = UAbilitySystemGlobals::Get();
const FGameplayTag& MissingTag = AbilitySystemGlobals.ActivateFailTagsMissingTag;
OptionalRelevantTags->AddTag(MissingTag);
}
FGameplayTagContainer MissingTags = RequiredTags;
MissingTags.RemoveTags(TagsToCheck.GetGameplayTagParents());
OptionalRelevantTags->AppendTags(MissingTags);
//计算缺失的标签并添加在OptionalRelevantTags
}
bMissing = true;
};
有其中任何一个标签都会被阻止
定义:
/** This ability is blocked if the activating actor/component has any of these tags */
UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="OwnedTagsCategory"))
FGameplayTagContainer ActivationBlockedTags;
还是老一套:
CheckForBlocked(AbilitySystemComponent.GetOwnedGameplayTags(), ActivationBlockedTags);
嘿你猜怎么着,到这我发现后边的四个标签原理都一样,RequiredTags就是必须的标签,没有的话此能力就会被阻止,BlockedTags就是不能有的标签,有的话此能力就会被阻止。
那么这些标签的区别是什么呢?
嘿嘿聪明的网友肯定都发现了,就是标签的来源不同,ActivatingActor可以理解为调用TryActivateAbility的实体,SourceActor就是这个能力的拥有者,就是被赋予能力的实体,而TargetActor就是作用的对象,应用GE的对象。
贴下这四个用到的位置:
跳着贴的但都在同一个方法里
//UGameplayAbility::DoesAbilitySatisfyTagRequirements中
if (SourceTags != nullptr)
{
CheckForBlocked(*SourceTags, SourceBlockedTags);
}
if (TargetTags != nullptr)
{
CheckForBlocked(*TargetTags, TargetBlockedTags);
}
if (SourceTags != nullptr)
{
CheckForRequired(*SourceTags, SourceRequiredTags);
}
if (TargetTags != nullptr)
{
CheckForRequired(*TargetTags, TargetRequiredTags);
}