Animation asset UAnimationAsset
type hierarchy structure
- UObjectBase
- UObjectBaseUtility
- UObject
- UAnimationAsset
- UAnimSequenceBase
- UAnimCompositeBase
- Animation Synthesis of UAnimComposite
- UAnimMontage animation Montage
- UAnimSequence animation sequence (note root motion)
- UAnimStreamable
- UAnimCompositeBase
- UBlendSpaceBase
- UBlendSpace mixed space
- UAimOffsetBlendSpace aim offset blend space
- UBlendSpace1D one dimensional mixed space
- Uaimoffsetblendspace 1D one dimensional aiming offset hybrid space
- UBlendSpace mixed space
- UPoseAsset
- UAnimSequenceBase
- UAnimationAsset
- UObject
- UObjectBaseUtility
C + + call
UAnimationAsset
-
Loaded are derived classes such as animation sequence and animation montage, which can be played directly
// load UAnimationAsset* AnimDead_I; AnimDead_I = LoadObject<UAnimationAsset>(nullptr, TEXT("AnimSequence'/Game/Res/PolygonAdventure/Mannequin/Enemy/Animation/FightGroup/Enemy_Dead_I.Enemy_Dead_I'")); // Load constructor use UAnimationAsset* DeadAnim ; static ConstructorHelpers::FObjectFinder<UAnimationAsset> StaticDeadAnim(TEXT("AnimSequence'/Game/Res/PolygonAdventure/Mannequin/Player/Animation/Player_Death.Player_Death'")); DeadAnim = StaticDeadAnim.Object; // Play, you can keep the last frame GetMesh()->PlayAnimation(DeadAnim, false); // Get duration AnimDead_I->GetMaxCurrentTime()
UAnimSequence
-
Can play directly
-
The length of time returned can be used for the behavior tree wait time
-
The returned transform can be used to Modify bone if necessary
-
Do not set cycle playback, you can freeze at the last frame
// load 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; // Get duration AnimAttackSeq_III->GetPlayLength() // Get transform AnimAttackSeq_III->GetBoneTransform(OutputTrans, 0.f, CurrentPlayTime, true);
UAnimMontage
-
Animation fusion can be realized through slot
-
If necessary, you need to set it to freeze the last frame
-
The length of the corresponding UAnimSequence can be used for the waiting time of the behavior tree
-
It can be played after judging each frame; Or play when you want to call, such as characer and UBTTaskNode
//play Montage_Play(AnimHurt); // Determine whether to play Montage_IsPlaying(AnimHurt) //Stop Montage void Montage_Stop(float InBlendOutTime, const UAnimMontage* Montage = NULL); Montage_Stop(0); // Stop all montages // Several methods related to the last frame of freeze frame GetMesh()->GlobalAnimRateScale = 0.f; GetMesh()->bNoSkeletonUpdate = true; GetMesh()->bPauseAnims = true;
Animation instance UAnimInstance and animation blueprint UAnimBlueprint
Article address https://www.cnblogs.com/shiroe/p/15634220.html
sketch
- Generally, when creating an animation blueprint, you need to select the Parent Class of UAnimInstance
- Therefore, after creating the UAnimInstance, write various variables and methods inside it, and then realize the communication between C + + and the blueprint through the animation blueprint. For example, variables are used for animation state machines, and events are used for calling animation notifications
- When Montage is first used, it is usually called in character. Later, it is found that it can also be used in UAnimInstance
C + + call
- Load animation blueprint
// Loading and setting static ConstructorHelpers::FClassFinder<UAnimInstance> StaticEnemyAnim(TEXT("AnimBlueprint'/Game/Blueprints/Enemy/BPA_Eneymy.BPA_Eneymy_C'")); // GetMesh()->SetAnimationMode(EAnimationMode::AnimationBlueprint); GetMesh()->SetAnimClass(StaticEnemyAnim.Class); // character get * * UAnimInstance** SEAnim = Cast<UEnemyAnim>(GetMesh()->GetAnimInstance());
Behavior tree related modules
-
UBTService can be used for data update
-
UBTDecorator
-
UBlackboardData blackboard data can be inherited by Data Asset under Editor
-
reload-able
virtual void PostLoad() override;
-
Add data, several types
//Waiting time FBlackboardEntry WaitTime; WaitTime.EntryName = FName(TEXT("WaitTime")); UBlackboardKeyType_Float* WaitTimeKeyType = NewObject<UBlackboardKeyType_Float>(); WaitTime.KeyType = WaitTimeKeyType; Keys.Add(WaitTime); //Enemy attack type FBlackboardEntry AttackType; AttackType.EntryName = FName(TEXT("AttackType")); UBlackboardKeyType_Enum* EnemyAttackTypeKeyType = NewObject<UBlackboardKeyType_Enum>(); // Get enumeration type through reflection EnemyAttackTypeKeyType->EnumType = FindObject<UEnum>(ANY_PACKAGE, *FString("EEnemyAttackType"), true); EnemyAttackTypeKeyType->EnumName = FString("EEnemyAttackType"); AttackType.KeyType = EnemyAttackTypeKeyType; Keys.Add(AttackType); // Player pointer FBlackboardEntry PlayerPawn; PlayerPawn.EntryName = FName(TEXT("PlayerPawn")); UBlackboardKeyType_Object* PlayerPawnKeyType = NewObject<UBlackboardKeyType_Object>(); PlayerPawnKeyType->BaseClass = ASLAiPlayerCharacter::StaticClass(); PlayerPawn.KeyType = PlayerPawnKeyType; Keys.Add(PlayerPawn); //Whether an action is completed FBlackboardEntry ProcessFinish; ProcessFinish.EntryName = FName(TEXT("ProcessFinish")); ProcessFinish.KeyType = NewObject<UBlackboardKeyType_Bool>(); Keys.Add(ProcessFinish);
-
-
UBTTaskNode
-
Rewritable function
// Override execution function virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override; //Override termination function virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override; // Set the blackboard data to associate UPROPERTY(EditAnywhere,Category="Blackboard") struct FBlackboardKeySelector WaitTime; UPROPERTY(EditAnywhere,Category="Blackboard") struct FBlackboardKeySelector Destination; UPROPERTY(EditAnywhere,Category="Blackboard") struct FBlackboardKeySelector IsActionFinish;
-
ExecuteTask
- You can obtain character and controller through the parameter OwnerComp, and then access related functions or data
- Can change blackboard data
SEController = Cast<AEnemyController>(OwnerComp.GetAIOwner()); SECharacter = Cast<AEnemyCharacter>(SEController->GetPawn()); // Using the navigation system to obtain random points UNavigationSystemV1::K2_GetRandomReachablePointInRadius(SEController, WanderOrigin,DesLoc, WanderRadius); OwnerComp.GetBlackboardComponent()->SetValueAsVector(Destination.SelectedKeyName, DesLoc); // Play the animation and return the duration float AttackDuration = SECharacter->PlayAttackAction(EEnemyAttackType::EA_Normal); OwnerComp.GetBlackboardComponent()->SetValueAsFloat(WaitTime.SelectedKeyName, AttackDuration);
-
AbortTask
- It is generally used for finishing work, such as clearing timer
-
Return value EBTNodeResult
- According to the return value, let the behavior tree continue to execute the child node or jump out and return to the parent node
// Return value return EBTNodeResult::Failed; return EBTNodeResult::Succeeded; return EBTNodeResult::Aborted;
-