中文字幕无码a片久久,亚洲日韩在线观看浪潮,人人超人人超碰超国产二区,国产人妻久久一区二区,国产人妻久久一区二区

福感科技有限公司 歡迎您!
聯(lián)系方式

    地址:北京市平谷區(qū)馬坊鎮(zhèn)金河北街17號(hào)院3號(hào)樓7層712

    電話(huà):010-89968230

    網(wǎng)站:http://0743119.com

如何在UE4中自定義動(dòng)畫(huà)藍(lán)圖

2021-1-2 22:38:13??????點(diǎn)擊:

動(dòng)畫(huà)藍(lán)圖提供了運(yùn)行特定操作的節(jié)點(diǎn),比如基于alpha值混合多個(gè)節(jié)點(diǎn)或者播放一個(gè)動(dòng)畫(huà)。 這里,您可以找到關(guān)于基本動(dòng)畫(huà)藍(lán)圖節(jié)點(diǎn)的更多信息。

這些節(jié)點(diǎn)提供了您將需要的標(biāo)準(zhǔn)功能,但是通常您應(yīng)用動(dòng)畫(huà)時(shí),一般需要?jiǎng)?chuàng)建自定義節(jié)點(diǎn)。這比較簡(jiǎn)單,但是卻需要您了解基礎(chǔ)系統(tǒng)的設(shè)計(jì)原理。該鏈接提供了關(guān)于該系統(tǒng)的深入知識(shí),但是這里我想著重強(qiáng)調(diào)一下基本系統(tǒng)的內(nèi)容,因?yàn)槲野l(fā)現(xiàn)有些人經(jīng)常會(huì)遇到問(wèn)題。

正如上面鏈接中所述的,系統(tǒng)需要兩個(gè)類(lèi):一個(gè)是您在編輯器中看到的圖表節(jié)點(diǎn),一個(gè)是真正在運(yùn)行時(shí)工作的行為節(jié)點(diǎn)。我們出于優(yōu)化目的將其分離開(kāi)來(lái)。節(jié)點(diǎn)構(gòu)建的性能消耗比較大,使用400個(gè)節(jié)點(diǎn)每30秒讓20個(gè)角色死亡或生成將會(huì)給內(nèi)存及CPU造成巨大負(fù)擔(dān)。如果您使用動(dòng)畫(huà)藍(lán)圖生成了一個(gè)角色,那么該角色將不會(huì)具有任何圖表節(jié)點(diǎn),僅具有行為節(jié)點(diǎn)。

讓我們比較一下動(dòng)畫(huà)圖表節(jié)點(diǎn)和動(dòng)畫(huà)行為節(jié)點(diǎn)的代碼:

動(dòng)畫(huà)圖表節(jié)點(diǎn)

class UAnimGraphNode_SequencePlayer : public UAnimGraphNode_Base

動(dòng)畫(huà)行為節(jié)點(diǎn)

struct ENGINE_API FAnimNode_SequencePlayer : public FAnimNode_Base

您將注意到這兩個(gè)節(jié)點(diǎn)的基類(lèi)是不同的:一個(gè)基類(lèi)是UObject,另一個(gè)的基類(lèi)是UStruct。在該博客中,我們將前一個(gè)作為動(dòng)畫(huà)圖表節(jié)點(diǎn),后一個(gè)作為動(dòng)畫(huà)行為節(jié)點(diǎn)。所有的圖表節(jié)點(diǎn)包含了類(lèi)似這樣的對(duì)應(yīng)行為節(jié)點(diǎn):

class UAnimGraphNode_SequencePlayer : public UAnimGraphNode_Base
{
    GENERATED_UCLASS_BODY()

    UPROPERTY(EditAnywhere, Category=Settings)
    FAnimNode_SequencePlayer Node;

}

該動(dòng)畫(huà)圖表節(jié)點(diǎn)知道另一個(gè)節(jié)點(diǎn)的存在,但反之則不能,這一個(gè)比較重要的區(qū)別。所有動(dòng)畫(huà)圖表節(jié)點(diǎn)都是出于這個(gè)原因存在于編輯器中的,因?yàn)樗粫?huì)隨同游戲加載,僅存在于編輯器中。另一方面,行為節(jié)點(diǎn)存在于運(yùn)行時(shí)代碼中,而這正是真正發(fā)生混合的地方。請(qǐng)確保您的類(lèi)指向正確的模塊。

這對(duì)骨架控制節(jié)點(diǎn)來(lái)說(shuō)也是一樣的。

動(dòng)畫(huà)圖表節(jié)點(diǎn)

class UAnimGraphNode_ModifyBone : public UAnimGraphNode_SkeletalControlBase

動(dòng)畫(huà)行為節(jié)點(diǎn)

struct ENGINE_API FAnimNode_ModifyBone : public FAnimNode_SkeletalControlBase

您將注意到骨架控制節(jié)點(diǎn)也具有不同的基類(lèi)。

該系統(tǒng)如此設(shè)計(jì),動(dòng)畫(huà)圖表節(jié)點(diǎn)負(fù)責(zé)任何編輯器工作,比如顯示節(jié)點(diǎn)名稱(chēng)、顯示工具提示信息或創(chuàng)建自定義引腳。動(dòng)畫(huà)行為節(jié)點(diǎn)負(fù)責(zé)實(shí)際工作,比如混合、計(jì)算目標(biāo)位置,及輸出正確姿勢(shì)。所以動(dòng)畫(huà)圖表節(jié)點(diǎn)在編輯器中是重要的,而動(dòng)畫(huà)行為節(jié)點(diǎn)則在運(yùn)行時(shí)是重要的。

再次說(shuō)明,請(qǐng)參照該鏈接來(lái)查看變量的元數(shù)據(jù)是如何變?yōu)楣?jié)點(diǎn)的輸入或輸出的。

比如,F(xiàn)PoseLink是傳入骨骼變換數(shù)組的姿勢(shì)連接,如果您像下面這樣聲明它,那么它將會(huì)像圖片中那樣顯示出來(lái)。


UPROPERTY(Category=Links)
FPoseLink BasePose;


知道FPoseLink如何工作比較重要,因?yàn)槿魏螘r(shí)候當(dāng)您調(diào)用任何動(dòng)畫(huà)函數(shù)時(shí),您也必須調(diào)用該P(yáng)ose函數(shù)。比如在您的Update函數(shù)中您應(yīng)該調(diào)用BasePose->Update。同樣,如果您有BasePose作為成員變量,您也應(yīng)該在CacheBones函數(shù)中調(diào)用BasePose->CacheBones。

現(xiàn)在,我想談下對(duì)于每種節(jié)點(diǎn)類(lèi)型您應(yīng)該關(guān)注的函數(shù)。我將不會(huì)集中介紹動(dòng)畫(huà)藍(lán)圖圖表節(jié)點(diǎn),因?yàn)樗魏纹渌{(lán)圖節(jié)點(diǎn)的工作方式比較類(lèi)似,但是我想集中介紹下這個(gè)真正工作的節(jié)點(diǎn)。

讓我們看下FAnimNode_Base節(jié)點(diǎn):

struct ENGINE_API FAnimNode_Base
{
    // Interface to implement
    virtual void Initialize(const FAnimationInitializeContext& Context) {}
    virtual void Update(const FAnimationUpdateContext& Context) {}
    virtual void Evaluate(FPoseContext& Output) { check(false); }
    virtual void CacheBones(const FAnimationCacheBonesContext& Context) {}
    virtual void GatherDebugData(FNodeDebugData& DebugData){}

};

它不是這么簡(jiǎn)單,但我正在進(jìn)行簡(jiǎn)化以?xún)H集中介紹您應(yīng)該關(guān)心的主要事情。

有三個(gè)決定了您的節(jié)點(diǎn)如何表現(xiàn)的主要函數(shù)。它們是Initialize、Update和Evaluate,這里是對(duì)它們應(yīng)用的簡(jiǎn)單描述:

  • Initialize - 任何時(shí)候當(dāng)您需要進(jìn)行初始化或重新初始化時(shí)調(diào)用該函數(shù)(當(dāng)修改實(shí)例的網(wǎng)格物體時(shí))。
  • Update - 調(diào)用該函數(shù)來(lái)更新當(dāng)前狀態(tài)(比如更新播放時(shí)間或混合權(quán)重)。該函數(shù)取入一個(gè)FAnimationUpdateContext,它知道更新的DeltaTime和當(dāng)前的節(jié)點(diǎn)混合權(quán)重。
  • Evaluate - 調(diào)用該函數(shù)來(lái)生成一個(gè)‘姿勢(shì)’(一系列的骨骼變換)。
    • 示例:
      • void FAnimNode_SequenceEvaluator::Evaluate(FPoseContext& Output)
        {
            if ((Sequence != NULL) && (Output.AnimInstance->CurrentSkeleton->IsCompatible(Sequence->GetSkeleton())))
            {
                Output.AnimInstance->SequenceEvaluatePose(Sequence, Output.Pose, FAnimExtractContext(ExplicitTime));
            }
            else
            {
                Output.ResetToRefPose();
            }
        }

    • Evaluate 判斷是否設(shè)置了序列及它是否同當(dāng)前骨架兼容。如果是,那么它將該骨骼變換填充到Output.Pose中。如果不是,則將Output設(shè)置為參考姿勢(shì)。


在這些基本函數(shù)的基礎(chǔ)上,您需要提供兩個(gè)函數(shù)的實(shí)現(xiàn),以確保您的節(jié)點(diǎn)可以正常同圖表的其他部分協(xié)同工作:

virtual void CacheBones(const FAnimationCacheBonesContext& Context) {}
virtual void GatherDebugData(FNodeDebugData& DebugData){}

CacheBones用于刷新該節(jié)點(diǎn)所引用的骨骼索引,GatherDebugData用于使用"ShowDebug Animation"數(shù)據(jù)進(jìn)行調(diào)試。為了保持到子項(xiàng)的連接,使用這些是很重要的。正如我之前所提到的,F(xiàn)PoseLink 應(yīng)該調(diào)用它下面的所有節(jié)點(diǎn),以確保您的節(jié)點(diǎn)連接的任何姿勢(shì)連接都會(huì)被調(diào)用。

請(qǐng)參照該示例:

void FAnimNode_BlendListBase::CacheBones(const FAnimationCacheBonesContext& Context)
{
    for(int32 ChildIndex=0; ChildIndex
    {
        BlendPose[ChildIndex].CacheBones(Context);
    }
}

您需要實(shí)現(xiàn)它,以便這些事件不會(huì)被您的節(jié)點(diǎn)阻止。

同時(shí)注意我們有FAnimationRuntime,當(dāng)進(jìn)行動(dòng)畫(huà)時(shí)它提供了大量功能。

這里是一個(gè)關(guān)于骨架控制節(jié)點(diǎn)的示例:

struct ENGINE_API FAnimNode_SkeletalControlBase : public FAnimNode_Base
{
    // FAnimNode_Base interface
    virtual void Initialize(const FAnimationInitializeContext& Context) override;
    virtual void CacheBones(const FAnimationCacheBonesContext& Context)  override;
    virtual void Update(const FAnimationUpdateContext& Context) override;
    virtual void EvaluateComponentSpace(FComponentSpacePoseContext& Output) override;
    // End of FAnimNode_Base interface
}

這同動(dòng)畫(huà)節(jié)點(diǎn)類(lèi)似但又有所不同,因?yàn)楣羌芸刂乒?jié)點(diǎn)在組件空間上工作。再次說(shuō)明,查看FAnimationRuntime將向您展示一種在本地空間和組件空間之間轉(zhuǎn)換的好方法。

您一般都使用EvaluateComponentSpace。這里是一個(gè)涉及到CopyBone節(jié)點(diǎn)的簡(jiǎn)單應(yīng)用示例:

void FAnimNode_CopyBone::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose& MeshBases, TArray& OutBoneTransforms)
{
    check(OutBoneTransforms.Num() == 0);
    // Pass through if we're not doing anything.
    if( !bCopyTranslation && !bCopyRotation && !bCopyScale )
    {
        return;
    }
    // Get component space transform for source and current bone.
    const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer();
    FCompactPoseBoneIndex TargetBoneIndex = TargetBone.GetCompactPoseIndex(BoneContainer);
    const FTransform& SourceBoneTM = MeshBases.GetComponentSpaceTransform(SourceBone.GetCompactPoseIndex(BoneContainer));
    FTransform CurrentBoneTM = MeshBases.GetComponentSpaceTransform(TargetBoneIndex);
    // Copy individual components
    if (bCopyTranslation)
    {
        CurrentBoneTM.SetTranslation( SourceBoneTM.GetTranslation() );
    }
    if (bCopyRotation)
    {
        CurrentBoneTM.SetRotation( SourceBoneTM.GetRotation() );
    }
    if (bCopyScale)
    {
        CurrentBoneTM.SetScale3D( SourceBoneTM.GetScale3D() );
    }
    // Output new transform for current bone.
    OutBoneTransforms.Add(FBoneTransform(TargetBoneIndex, CurrentBoneTM));
}

其目的是在OutBoneTransforms中返回您想要的數(shù)據(jù)。您可以返回您需要的任何數(shù)量的骨骼變換,但請(qǐng)注意層次結(jié)構(gòu)。保持父項(xiàng)到子項(xiàng)的順序?qū)⒛艽_??偸前踩?。

聲明:文章內(nèi)容整理來(lái)源于網(wǎng)絡(luò),版權(quán)屬于原作者,如有問(wèn)題,請(qǐng)聯(lián)系我們!

Copyright 2019 0743119.com

福感科技有限公司 版權(quán)所有 All Rights Reserved

京ICP備20002031號(hào)

010-89968230