不使用角色蓝图、动画蓝图、状态机,用“24K纯C++”实现动画播放
发表于2016-06-16
原文作者:@玄冬Wong
不好意思,我稍稍标题党了,目前还不清楚如何用C++代码来实现BlendSpace和Montage的逻辑,如果这两个文件也不我们创建了,那么以下内容就是真正意义上的纯C++实现角色蓝图和动画蓝图。
逻辑用C++,动画处理用蓝图,对于有一定复杂度的项目来说这种做法很不方便,最方便的方式就是所有跟蓝图相关的操作能够让C++编码实现。即使是简单项目,但是如果模型数量有几十个,每个模型的动画切换逻辑是一样的,让你给每一个模型编辑动画状态机也是个体力活,所以如果这些可以用C++代码实现的话,只写一遍动画操作的逻辑,就可以一劳永逸。
用C++代码指定Actor的SkeletalMesh
用过蓝图的都知道,一般指定SkeletalMesh是在角色蓝图中指定的:
现在没有角色蓝图了,设置SkeletalMesh的C++代码如下:
1 2 3 | USkeletalMesh* MyMesh = LoadObject "SkeletalMesh'/Game/MyMesh.MyMesh'" )); MyActor* Actor = World->SpawnActor Actor->GetMesh()->SetSkeletalMesh(MyMesh); |
用C++代码播放BlendSpace (1D、2D、3D均可)
因为动画蓝图也没有了,所以播放BlendSpace和AnimationSequence也通过C++代码实现
1、先定义一个UPROPERTY变量,并在编辑器中设置该BlendSpace
1 2 | UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Anims" ) UBlendSpace1D *BlendSpace; |
2、设置BlendSpace参数并播放动画,这里BlendSpace假设以X轴为方向
需要包含头文件:#include "Runtime/Engine/Classes/Animation/SkeletalMeshActor.h"
1 2 3 4 5 6 7 8 9 10 11 | ASkeletalMeshActor *Skel = Cast if (Skel) { USkeletalMeshComponent *Mesh = Skel->GetSkeletalMeshComponent(); if (Mesh) { Mesh->PlayAnimation(BlendSpace, true ); FVector BlendParams(50.0f, 0.0f, 0.0f); Mesh->GetSingleNodeInstance()->SetBlendSpaceInput(BlendParams); } } |
用C++代码在指定Slot位置播放AnimationSequence
1、先定义一个UPROPERTY变量,并在编辑器中设置该UAnimSequence
1 2 | UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Anims" ); UAnimSequence *MyAnimSequence; |
1 2 3 4 5 6 7 8 9 10 | USkeletalMeshComponent *Mesh = MyActor->FindComponentByClass if (Mesh) { UAnimInstance *AnimInst = Mesh->GetAnimInstance(); if (AnimInst) { AnimInst->PlaySlotAnimationAsDynamicMontage(MyAnimSequence, TEXT( "UpperBody" ), 0.1f, 0.1f, 1.0f, 30.0f); } }
|
注:GetAnimInstance之前需要SetAnimInstanceClass,如何设置,参见:
3、播放AnimMontage:
1 2 | MyAnimTimer = AnimInstance->Montage_Play(MyMontage); GetWorldTimerManager().SetTimer(PauseMontageTimerHandle, this , &MyActor::PauseMontageFunc, MyAnimTimer, false ); |
上面例子中UBlendSpace1D和UAnimSequence变量可以在编辑器中设置以外,也可以通过C++代码加载设置,具体方法:
C++实现动态加载的问题:LoadClass()和LoadObject()