【UE4 C++ 】動畫與行為樹相關模塊初步使用


注意添加模塊 "AIModule", "GamePlayTasks", "NavigationSystem"

動畫資源 UAnimationAsset

類層級結構

  • UObjectBase
    • UObjectBaseUtility
      • UObject
        • UAnimationAsset
          • UAnimSequenceBase
            • UAnimCompositeBase
              • UAnimComposite 動畫合成
              • UAnimMontage 動畫蒙太奇
            • UAnimSequence 動畫序列 (注意 root motion)
            • UAnimStreamable
          • UBlendSpaceBase
            • UBlendSpace 混合空間
              • UAimOffsetBlendSpace 瞄准偏移混合空間
            • UBlendSpace1D 一維混合空間
              • UAimOffsetBlendSpace1D 一維瞄准偏移混合空間
          • UPoseAsset

C++ 調用

UAnimationAsset

  • 加載的是如動畫序列、動畫蒙太奇等派生類,可直接播放

    // 加載
    UAnimationAsset* AnimDead_I;
    AnimDead_I = LoadObject<UAnimationAsset>(nullptr, TEXT("AnimSequence'/Game/Res/PolygonAdventure/Mannequin/Enemy/Animation/FightGroup/Enemy_Dead_I.Enemy_Dead_I'"));
    
    // 加載 構造函數使用
    UAnimationAsset* DeadAnim ; 
    static ConstructorHelpers::FObjectFinder<UAnimationAsset> StaticDeadAnim(TEXT("AnimSequence'/Game/Res/PolygonAdventure/Mannequin/Player/Animation/Player_Death.Player_Death'"));
    DeadAnim = StaticDeadAnim.Object;
    
    // 播放,可以保留最后一幀
    GetMesh()->PlayAnimation(DeadAnim, false);
    
    // 獲取時長
    AnimDead_I->GetMaxCurrentTime()
    

UAnimSequence

  • 可直接播放

  • 返回的時長可用於行為樹等待時間

  • 返回的 transform 可以用於 Modify bone,如果有需要的話

  • 不設置循環播放,可以定格在最后一幀

    // 加載
    static ConstructorHelpers::FObjectFinder<UAnimSequence> StaticAnimAttackSeq_III(TEXT("AnimSequence'/Game/Res/PolygonAdventure/Mannequin/Enemy/Animation/FightGroup/Enemy_Attack_III.Enemy_Attack_III'"));
    UAnimSequence* AnimAttackSeq_III;
    AnimAttackSeq_III = StaticAnimAttackSeq_III.Object;
    
    // 獲取時長
    AnimAttackSeq_III->GetPlayLength()
    // 獲取 transform
    AnimAttackSeq_III->GetBoneTransform(OutputTrans, 0.f, CurrentPlayTime, true);
    

UAnimMontage

  • 可以通過slot,實現動畫融合

  • 如果需要的話,需要設置使其定格最后一幀;或者在屬性設置里不勾選 "enable auto blend out"

  • 可配合 對應 UAnimSequence 的長度用於行為樹等待時間

  • 可在每幀進行判斷后播放;或者想要調用時播放,例如characer、UBTTaskNode

    //播放
    Montage_Play(AnimHurt);
    
    // 判斷是否播放
    Montage_IsPlaying(AnimHurt)
    
    //停止蒙太奇
    void Montage_Stop(float InBlendOutTime, const UAnimMontage* Montage = NULL);
    Montage_Stop(0); // 停止所有蒙太奇
    
    // 與定格最后一幀相關的幾種方式
    GetMesh()->GlobalAnimRateScale = 0.f;
    GetMesh()->bNoSkeletonUpdate = true;
    GetMesh()->bPauseAnims = true;
    

動畫實例UAnimInstance 與 動畫藍圖UAnimBlueprint

本文地址 https://www.cnblogs.com/shiroe/p/15634220.html

簡述

  • 一般創建動畫藍圖時需要選擇 UAnimInstance 的Parent Class
  • 因此創建 UAnimInstance 后,在其內部寫各種變量和方法,再通過動畫藍圖可以實現C++與藍圖之間的通信。比如變量用於動畫狀態機,事件用於動畫通知的調用
  • 剛開始使用 Montage 時,一般會在 character 里調用,后來發現其實也可以放進 UAnimInstance 里面使用

C++ 調用

  • 重寫 NativeUpdateAnimation 函數,類似Tick

    virtual void NativeUpdateAnimation(float DeltaSeconds) override;
    
  • 加載動畫藍圖

    // 加載與設置
    static  ConstructorHelpers::FClassFinder<UAnimInstance> StaticEnemyAnim(TEXT("AnimBlueprint'/Game/Blueprints/Enemy/BPA_Eneymy.BPA_Eneymy_C'"));
    // GetMesh()->SetAnimationMode(EAnimationMode::AnimationBlueprint);
    GetMesh()->SetAnimClass(StaticEnemyAnim.Class);
    
    // character 獲取**UAnimInstance** 
    SEAnim = Cast<UEnemyAnim>(GetMesh()->GetAnimInstance());
    
    

行為樹相關模塊

  • UBTService 可用於數據更新

  • UBTDecorator

  • UBlackboardData 黑板數據,Editor下可以使用 Data Asset 繼承之

    • 可重載

      virtual void PostLoad() override;
      
    • 添加數據,幾種類型

      //等待時長
      FBlackboardEntry WaitTime;
      WaitTime.EntryName = FName(TEXT("WaitTime"));
      UBlackboardKeyType_Float* WaitTimeKeyType = NewObject<UBlackboardKeyType_Float>();
      WaitTime.KeyType = WaitTimeKeyType;
      Keys.Add(WaitTime);
      
      //敵人攻擊類型
      FBlackboardEntry AttackType;
      AttackType.EntryName = FName(TEXT("AttackType"));
      UBlackboardKeyType_Enum* EnemyAttackTypeKeyType = NewObject<UBlackboardKeyType_Enum>();
      // 通過反射獲取枚舉類型
      EnemyAttackTypeKeyType->EnumType = FindObject<UEnum>(ANY_PACKAGE, *FString("EEnemyAttackType"), true);
      EnemyAttackTypeKeyType->EnumName = FString("EEnemyAttackType");
      AttackType.KeyType = EnemyAttackTypeKeyType;
      Keys.Add(AttackType);
      
      // 玩家指針
      FBlackboardEntry PlayerPawn;
      PlayerPawn.EntryName = FName(TEXT("PlayerPawn"));
      UBlackboardKeyType_Object* PlayerPawnKeyType = NewObject<UBlackboardKeyType_Object>();
      PlayerPawnKeyType->BaseClass = ASLAiPlayerCharacter::StaticClass();
      PlayerPawn.KeyType = PlayerPawnKeyType;
      Keys.Add(PlayerPawn);
      
      //某一個動作是否完成
      FBlackboardEntry ProcessFinish;
      ProcessFinish.EntryName = FName(TEXT("ProcessFinish"));
      ProcessFinish.KeyType = NewObject<UBlackboardKeyType_Bool>();
      Keys.Add(ProcessFinish);
      
  • UBTTaskNode

    • 可重寫函數

      // 重寫執行函數
      virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
      //重寫終止函數
      virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override;
      
      // 設置要關聯的黑板數據
      UPROPERTY(EditAnywhere,Category="Blackboard")
      		struct FBlackboardKeySelector WaitTime;
      UPROPERTY(EditAnywhere,Category="Blackboard")
      		struct FBlackboardKeySelector Destination;
      UPROPERTY(EditAnywhere,Category="Blackboard")
      		struct FBlackboardKeySelector IsActionFinish;
      
    • ExecuteTask

      • 可通過參數 OwnerComp獲取 character 和 controller,進而訪問相關函數或數據
      • 可更改黑板數據
      SEController = Cast<AEnemyController>(OwnerComp.GetAIOwner());
      SECharacter = Cast<AEnemyCharacter>(SEController->GetPawn());
      
      // 使用導航系統獲取隨機點
      UNavigationSystemV1::K2_GetRandomReachablePointInRadius(SEController, WanderOrigin,DesLoc, WanderRadius);
      OwnerComp.GetBlackboardComponent()->SetValueAsVector(Destination.SelectedKeyName, DesLoc);
      
      // 播放動畫,返回時長
      float AttackDuration = SECharacter->PlayAttackAction(EEnemyAttackType::EA_Normal);
      OwnerComp.GetBlackboardComponent()->SetValueAsFloat(WaitTime.SelectedKeyName, AttackDuration);
      
    • AbortTask

      • 一般用於收尾工作,比如清除定時器
    • 返回值 EBTNodeResult

      • 根據返回值,讓行為樹繼續執行子節點或者跳出返回父節點
      // 返回值
      return EBTNodeResult::Failed;
      return EBTNodeResult::Succeeded;
      return EBTNodeResult::Aborted;
      


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM