一、直接使用GameplayEffect
1.ApplyGameplayEffectToSelf
直接使用GameplayEffect修改自身属性
函数定义:
FActiveGameplayEffectHandle UAbilitySystemComponent::ApplyGameplayEffectToSelf(
const UGameplayEffect *GameplayEffect,
float Level,
const FGameplayEffectContextHandle& EffectContext,
FPredictionKey PredictionKey = FPredictionKey()
)
参数:
- GameplayEffect: 使用的GameplayEffect类
- Level: 触发这个GE的等级, GE中使用CurveTable中哪个等级的数值
- EffectContext: 设置一些信息 比如触发这个GE的Actor、Ability是什么
- PredictionKey: 预测键 主要为了确保客户端与服务端的结果一致
示例:
UPROPERTY(EditDefaultsOnly, Category = "StartUpData")
TArray<TSubclassOf<UGameplayEffect>> StartUpGameplayEffects;
...
for (const TSubclassOf<UGameplayEffect>& EffectClass : StartUpGameplayEffects)
{
if (!EffectClass) continue;
UGameplayEffect* EffectCDO=EffectClass->GetDefaultObject<UGameplayEffect>();
InASCToGive->ApplyGameplayEffectToSelf(
EffectCDO,
ApplyLevel,
InASCToGive->MakeEffectContext()
);
}
2.ApplyGameplayEffectToTarget
直接使用GameplayEffect修改目标属性 逻辑与上相同
函数定义:
FActiveGameplayEffectHandle UAbilitySystemComponent::ApplyGameplayEffectToTarget(
UGameplayEffect *GameplayEffect,
UAbilitySystemComponent *Target,
float Level,
FGameplayEffectContextHandle Context,
FPredictionKey PredictionKey
)
参数:
- Target:传入目标的ASC
二、使用GameplayEffectSpec
使用GameplayEffectSpec 修改属性
其实前两个函数也是在内部创建了GameplayEffectSpec
1.MakeOutgoingSpec
创建一个可用的GameplayEffectSpec 并返回其Handle
函数定义:
virtual FGameplayEffectSpecHandle UAbilitySystemComponent::MakeOutgoingSpec(
TSubclassOf<UGameplayEffect> GameplayEffectClass,
float Level,
FGameplayEffectContextHandle Context
) const;
参数与上相同
2.ApplyGameplayEffectSpecToSelf
使用GameplayEffectSpec修改自身属性
函数定义:
virtual FActiveGameplayEffectHandle UAbilitySystemComponent::ApplyGameplayEffectSpecToSelf(
const FGameplayEffectSpec& GameplayEffect,
FPredictionKey PredictionKey = FPredictionKey()
);
传入的GameplayEffectSpec 可通过*GameplayEffectSpecHandle.Data获得
3.ApplyGameplayEffectSpecToTarget
使用GameplayEffectSpec修改目标属性
函数定义:
virtual FActiveGameplayEffectHandle UAbilitySystemComponent::ApplyGameplayEffectSpecToTarget(
const FGameplayEffectSpec& GameplayEffect,
UAbilitySystemComponent *Target,
FPredictionKey PredictionKey=FPredictionKey()
);
传入GameplayEffectSpec和目标的ASC
4.示例
首先MakeOutgoingSpec
然后ApplyGameplayEffectSpecToTarget
可以结合FGameplayEffectContext和SetByCaller传递更多信息
//MyAbility.cpp
//创建FGameplayEffectContext
FGameplayEffectContextHandle ContextHandle = MyASC->MakeEffectContext();
ContextHandle.SetAbility(this);
ContextHandle.AddSourceObject(AvatorActor);
ContextHandle.AddInstigator(AvatorActor,AvatorActor);
//MakeOutgoingSpec
FGameplayEffectSpecHandle EffectSpecHandle = MyASC->MakeOutgoingSpec(
EffectClass,
GetAbilityLevel(),
ContextHandle
);
//SetByCaller
EffectSpecHandle.Data->SetSetByCallerMagnitude(
MyGameplayTags::SetByCaller_BaseDamage,
BaseDamage
);
//ApplyGameplayEffectSpecToTarget
MyASC->ApplyGameplayEffectSpecToTarget(
*EffectSpecHandle.Data,
TargetASC
);
三、移除GameplayEffect
对于持续性的GE 有时我们需要手动移除它
1. 通过GameplayEffect类移除
示例:
TSubclassOf<UGameplayEffect> EffectClass = UMyGameplayEffect::StaticClass();
AbilitySystemComponent->RemoveActiveGameplayEffectBySourceEffect(EffectClass);
2.使用ActiveGameplayEffectHandle移除
virtual bool RemoveActiveGameplayEffect(
FActiveGameplayEffectHandle Handle,
int32 StacksToRemove=-1
);
ActiveGameplayEffectHandle可以通过ApplyEffect…函数的返回值获得
StacksToRemove表示移除几层 为-1则表示全部移除
示例:
AbilitySystemComponent->RemoveActiveGameplayEffect(ActiveHandle);
3.通过GameplayEffect的自身的标签移除
如果不知道Handle还可以用Tag移除
GameplayEffect有两种标签:
Asset Tags:用于标识 GameplayEffect的标签 这是我们现在需要的
Granted Tags:附加到目标角色ASC上的标签 比如可以标识角色进入了中毒状态
为GE添加标签:
蓝图方式:
在GameplayEffect下的Component中
c++方式
UGameplayEffect* PoisonEffect = NewObject();
PoisonEffect->InheritableGameplayEffectTags.AddTag(MyGameplayTag::Effect_Poison);
用标签移除GE
AbilitySystemComponent->RemoveActiveEffectsWithTags( \
MyGameplayTag::Effect_Poison.GetSingleTagContainer() \
);
4.移除目标角色身上的标签 以停止GE
要求目标身上必须由标签 GE才能继续运行
移除标签之后GE停止 注意 这时候GE并没有被移除