• 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。

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

  • 相关阅读:
    Java中使用Jedis操作Redis
    Predicate与filter
    Joiner的用法
    Immutable集合
    【Excle数据透视】如何在数据透视表字段列表中显示更多的字段
    【Excle数据透视表】如何显示/隐藏数据透视表字段列表
    【Excle数据透视】如何创建多条件汇总的数据透视表
    【Excle数据透视表】如何创建非共享缓存的数据透视表
    【Excle数据透透视表】如何删除数据透视表
    【Excle数据透视表】如何复制数据透视表
  • 原文地址:https://www.cnblogs.com/corgi/p/5405872.html
Copyright © 2020-2023  润新知