注意添加模塊 "AIModule", "GamePlayTasks", "NavigationSystem"
動畫資源 UAnimationAsset
類層級結構
- UObjectBase
- UObjectBaseUtility
- UObject
- UAnimationAsset
- UAnimSequenceBase
- UAnimCompositeBase
- UAnimComposite 動畫合成
- UAnimMontage 動畫蒙太奇
- UAnimSequence 動畫序列 (注意 root motion)
- UAnimStreamable
- UAnimCompositeBase
- UBlendSpaceBase
- UBlendSpace 混合空間
- UAimOffsetBlendSpace 瞄准偏移混合空間
- UBlendSpace1D 一維混合空間
- UAimOffsetBlendSpace1D 一維瞄准偏移混合空間
- UBlendSpace 混合空間
- UPoseAsset
- UAnimSequenceBase
- UAnimationAsset
- UObject
- UObjectBaseUtility
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;
-
