zoukankan      html  css  js  c++  java
  • GetRelevantAnimTimeRemainingFraction节点Bug

    初始设置:

    动画状态机:

    MoveStop->Idle的条件:

    使用该节点的目的:

    在动画蓝图的过渡条件中使用该节点,保证上一个状态的动作完成后进入下一个动作。需求是MoveStop动作完成后才能进入Idle状态。

    Bug现象:

    启动游戏后,第一次进入该状态时会直接过渡到Idle状态。

    此时状态机的状态:

    状态机条件:

    但是之后再次进入该状态就会正常。状态只会在Move和MoveStop之间过渡。BUG只在启动游戏后第一次进入该状态时出现。

    原因:

    float UAnimInstance::GetRelevantAnimTimeRemainingFraction(int32 MachineIndex, int32 StateIndex)
    
    {
    
        if(FAnimNode_AssetPlayerBase* AssetPlayer = GetRelevantAssetPlayerFromState(MachineIndex, StateIndex))//AssetPlayer在这里是NULL
    
        {
    
            if(AssetPlayer->GetAnimAsset())
    
            {
    
                float Length = AssetPlayer->GetAnimAsset()->GetMaxCurrentTime();
    
                if(Length > 0.0f)
    
                {
    
                    return (Length - AssetPlayer->GetAccumulatedTime()) / Length;
    
                }
    
            }
    
        }
    
     
    
        return 0.0f;
    
    }

      

    断点后发现第一次进入该状态时,AssetPlayer为NULL。

    FAnimNode_AssetPlayerBase* UAnimInstance::GetRelevantAssetPlayerFromState(int32 MachineIndex, int32 StateIndex)
    
    {
    
        FAnimNode_AssetPlayerBase* ResultPlayer = nullptr;
    
        if(FAnimNode_StateMachine* MachineInstance = GetStateMachineInstance(MachineIndex))
    
        {
    
            float MaxWeight = 0.0f;
    
            const FBakedAnimationState& State = MachineInstance->GetStateInfo(StateIndex);
    
            for(const int32& PlayerIdx : State.PlayerNodeIndices)
    
            {
    
                if(FAnimNode_AssetPlayerBase* Player = GetNodeFromIndex<FAnimNode_AssetPlayerBase>(PlayerIdx))
    
                {
    
                    if(!Player->bIgnoreForRelevancyTest && Player->GetCachedBlendWeight() > MaxWeight)
    
                    {
    
                        MaxWeight = Player->GetCachedBlendWeight();
    
                        ResultPlayer = Player;
    
                    }
    
                }
    
            }
    
        }
    
        return ResultPlayer;
    
    }

    再进入GetRelevantAssetPlayerFromState查看到Player->GetCachedBlendWeight返回结果均为0.

    由于状态机切换状态时先执行条件判断,再执行AnimNode的Update。所以未Update过的FAnimNode_AssetPlayerBase的BlendWeight都是0.导致返回的ResultPlayer是nullptr。

    void FAnimNode_AssetPlayerBase::Update(const FAnimationUpdateContext& Context)
    
    {
    
        // Cache the current weight and update the node
    
        BlendWeight = Context.GetFinalBlendWeight();
    
        UpdateAssetPlayer(Context);
    
    }

    解决办法:

    避免GetRelevantAnimTimeRemainingFraction==0。小于0.1且不等于0,过渡条件为true。

    注:可能是我自己使用上的问题,若有正确使用方法请告知。

  • 相关阅读:
    PHP ftp_nb_continue() 函数
    PHP ftp_mkdir() 函数
    PHP ftp_mdtm() 函数
    普通索引和唯一索引,应该怎么选择
    [学习笔记]拉格朗日中值定理
    asp dotnet core 通过图片统计 csdn 用户访问
    WPF 使用 SharpDx 异步渲染
    WPF 使用 SharpDx 异步渲染
    win10 uwp 解决 SerialDevice.FromIdAsync 返回空
    win10 uwp 解决 SerialDevice.FromIdAsync 返回空
  • 原文地址:https://www.cnblogs.com/corgi/p/5405872.html
Copyright © 2011-2022 走看看