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

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

  • 相关阅读:
    foreach next 操作数组指针移动问题,多个数连加,连除,连减,连乘php版本
    mysql 5.7 laravel json类型数据相关操作
    rbac权限控制,基于无线分类
    基于bootstrap-treeview做的一个漂亮的无限分类树层级联动菜单
    css页面字体替换源代码和页面显示不一样问题解决
    centos6.8 编译安装lnmp php7.2 mysql5.6 nginx1.1.4
    mysql5.7采坑
    laravel整合vue 多入口解决
    使用mysql设计一个全局订单生产计数器
    laravel整合workerman做聊天室
  • 原文地址:https://www.cnblogs.com/corgi/p/5405872.html
Copyright © 2020-2023  润新知