问题和分析
初始问题是这样的

Lyra的开火写法是这样的。GA里面给目标加一个 伤害的GE,GE配置了一个受击的Cue。
一模一样的写法在我这播放不了受击动画。
写到C++一样的代码,却是正常的
if (SpecHandle.IsValid() && K2_HasAuthority())
{
auto CurPredictionKey = MyAbilityComponent->ScopedPredictionKey;
MyAbilityComponent->ApplyGameplayEffectSpecToTarget(*SpecHandle.Data.Get(), TargetASC);
}
写成这样有问题,怀疑蓝图是这样的路径
if (SpecHandle.IsValid() && K2_HasAuthority())
{
auto CurPredictionKey = MyAbilityComponent->ScopedPredictionKey;
MyAbilityComponent->ApplyGameplayEffectSpecToTarget(*SpecHandle.Data.Get(), TargetASC, CurPredictionKey);
}
问题基本可以确定:
客户端生成一个预测key。发给服务器,服务器认为没问题。广播。
广播的客户端有一个相同的key,服务器认为你是先行的客户端,就跳过这个GE的流程。就行这部分C++代码。
蓝图的调用路径中,这个地方会获得一个预测key。
TArray<FActiveGameplayEffectHandle> UGameplayAbility::ApplyGameplayEffectSpecToTarget(const FGameplayAbilitySpecHandle AbilityHandle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEffectSpecHandle SpecHandle, const FGameplayAbilityTargetDataHandle& TargetData) const
{
TArray<FActiveGameplayEffectHandle> EffectHandles;
if (SpecHandle.IsValid() && HasAuthorityOrPredictionKey(ActorInfo, &ActivationInfo))
{
TARGETLIST_SCOPE_LOCK(*ActorInfo->AbilitySystemComponent);
for (TSharedPtr<FGameplayAbilityTargetData> Data : TargetData.Data)
{
if (Data.IsValid())
{
EffectHandles.Append(Data->ApplyGameplayEffectSpec(*SpecHandle.Data.Get(), ActorInfo->AbilitySystemComponent->GetPredictionKeyForNewAction()));
}
else
{
ABILITY_LOG(Warning, TEXT("UGameplayAbility::ApplyGameplayEffectSpecToTarget invalid target data passed in. Ability: %s"), *GetPathName());
}
}
}
return EffectHandles;
}
一直上去到,BP_ApplyGameplayEffectToTarget 这里也没有其他分支。应该就是这个情况。
那么这里确实不能加权威判断。
如果去Lyra的同一个地方断点呢?
FActiveGameplayEffectHandle UAbilitySystemComponent::ApplyGameplayEffectSpecToTarget(const FGameplayEffectSpec &Spec, UAbilitySystemComponent *Target, FPredictionKey PredictionKey)
{
SCOPE_CYCLE_COUNTER(STAT_AbilitySystemComp_ApplyGameplayEffectSpecToTarget);
UAbilitySystemGlobals& AbilitySystemGlobals = UAbilitySystemGlobals::Get();
if (!AbilitySystemGlobals.ShouldPredictTargetGameplayEffects())
{
// If we don't want to predict target effects, clear prediction key
PredictionKey = FPredictionKey();
}
}
蛤!!!
bool UAbilitySystemGlobals::ShouldPredictTargetGameplayEffects() const
{
return GetDefault<UGameplayAbilitiesDeveloperSettings>()->PredictTargetGameplayEffects;
}
DefaultGame.ini
[/Script/GameplayAbilities.AbilitySystemGlobals]
PredictTargetGameplayEffects=False
Lyra直接关了