Lyra 开火预测问题记录

问题和分析

初始问题是这样的

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直接关了

上一篇
下一篇