• [UE4][Custom Animation Graph Node]Evaluate Pose by Curve


    转自:http://www.cnblogs.com/corgi/p/5405447.html

    目的:根据曲线值获得当前动作帧。用于实现各种通过曲线同步的功能。

    方法:继承FAnimNode_Base创建自定义动画节点。重写Evaluate部分。创建相应的AnimGraphNode。

    Evaluate : 1. 根据曲线Value(Y轴)值获得Time(X轴)值。

    曲线KeyArray所在位置。AnimSequenceBase : RawCurveData.

    类型AnimCurveTypes.h:FRawCurveTracks

    曲线记录是TArray<FRichCurveKey>。每个key中存有Time和Value。根据输入的CurveValue,遍历Array查找Value最接近的Key,返回Time。

    2.根据Time值获得动画POS

    AnimSequence->GetAnimationPose(…, Time, …)输出Pose。

    /*! 
     * file AnimNode_EvaluatePose.h 
     * date 2016/03/29 17:45 
     * 
     * author: Jia Zhipeng 
     * Contact: jiazhipeng@pwrd.com 
     * 
     * rief: 根据曲线获得当前Pose. Get Pose based on curve value. 
     * 
     * 
    ote:  
    */  
    #pragma once  
    #include "Animation/AnimNodeBase.h"  
    //#include "AnimNode_SkeletalControlBase.h"  
    #include "AnimNode_EvaluatePose.generated.h"  
      
    USTRUCT()  
    struct FAnimNode_EvaluatePose :public FAnimNode_Base  
    {  
        GENERATED_USTRUCT_BODY()  
      
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Settings, meta = (PinShownByDefault))  
        UAnimSequenceBase* Sequence;  
      
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Settings, meta = (PinShownByDefault))  
            FName CurveName;  
      
        UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Settings, meta = (PinShownByDefault))  
            float CurveValue;  
      
        UAnimInstance* MyInstance;  
    public:  
        //  Constructor  
        FAnimNode_EvaluatePose();  
      
        // FAnimNode_Base interface  
        virtual void Initialize(const FAnimationInitializeContext& Context) override;  
        virtual void CacheBones(const FAnimationCacheBonesContext& Context) override;  
        virtual void Evaluate(FPoseContext& Output) override;  
        virtual void OverrideAsset(UAnimationAsset* NewAsset) override;  
        virtual void GatherDebugData(FNodeDebugData& DebugData) override;  
        // End of FAnimNode_Base interface//  
      
    };  
    //Iterate Animation's curve's keys to get current time  
    void FAnimNode_EvaluatePose::Evaluate(FPoseContext& Output)  
    {     
    //CurveValue is connected to AnimInstance’s variable in AnimBlueprint, but it is not updated when executing this node. So how to get variable of AnimInstance? 2 ways.  
    //1. EvaluateGraphExposedInputs.Execute(Output); Cause crash. Explore this method in the future.  
    //2. Get property from AnimInstance. But in this way, the variable’s name has to be specified. Temporarily use this method.  
        UFloatProperty* FloatProp = Cast<UFloatProperty>(PW_PropertyTools::FindProperty(MyInstance, TEXT("Horiz Movement Speed")));  
        if (!FloatProp)  
        {  
            UE_LOG(LogTemp, Warning, TEXT("Horiz Movement Speed Not found"));  
            return;  
        }  
        float HorzSpeed = FloatProp->GetPropertyValue_InContainer(MyInstance);  
        CurveValue = HorzSpeed;  
          
        USkeleton* Skeleton = Sequence->GetSkeleton();  
        if (!Skeleton)  
        {  
            UE_LOG(LogTemp, Warning, TEXT("FAnimNode_EvaluatePose::Evaluate fail to find skeleton"));  
            return;  
        }  
        FSmartNameMapping* NameMapping = Skeleton->SmartNames.GetContainer(USkeleton::AnimCurveMappingName);  
        // retrieve curve  
        USkeleton::AnimCurveUID Uid;  
        if (!NameMapping->Exists(CurveName))  
        {  
            UE_LOG(LogTemp, Warning, TEXT("FAnimNode_EvaluatePose::Evaluate fail to find curve %s"), *CurveName.ToString());  
            return;  
        }  
      
        Uid = *NameMapping->FindUID(CurveName);  
        FFloatCurve * CurveToCompute = static_cast<FFloatCurve*>(Sequence->RawCurveData.GetCurveData(Uid));  
        if (!CurveToCompute)  
        {  
            UE_LOG(LogTemp, Warning, TEXT("FAnimNode_EvaluatePose::Evaluate fail to find curve %s"), *CurveName.ToString());  
            return;  
        }  
      
        auto FloatCurve = CurveToCompute->FloatCurve;  
        float OutTime = 0.0f;  
        BinarySeach(FloatCurve, CurveValue, OutTime);  
        if ((Sequence != NULL) && (Output.AnimInstance->CurrentSkeleton->IsCompatible(Sequence->GetSkeleton())))  
        {  
            Sequence->GetAnimationPose(Output.Pose, Output.Curve, FAnimExtractContext(OutTime, Output.AnimInstance->ShouldExtractRootMotion()));  
        }  
        else  
        {  
            Output.ResetToRefPose();  
        }  
    }  
  • 相关阅读:
    vscode开发环境安装配置-连载【2】-企业级系统开发实战连载系列 -技术栈(vue、element-ui、qt、c++、sqlite)
    nodejs开发环境安装-连载【1】-企业级系统开发实战连载系列 -技术栈(vue、element-ui、qt、c++、sqlite)
    vs 2015 菜单重复的问题解决方法
    ecshop代码详解之init.php
    前端jquery实现点击图片弹出大图层(且滚动鼠标滑轮图片缩放)
    thinkPHP中省市级联下拉列表
    mysql函数date_format统计刷选按年月日统计的数据
    jQuery插件实现select下拉框左右选择_交换内容(multiselect2side)
    php代码生成二维码
    ASP.NET无效的视图
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/8444100.html
Copyright © 2020-2023  润新知