转自:https://forums.unrealengine.com/development-discussion/c-gameplay-programming/104831-creating-and-using-a-blendspace-in-c

creating and using a blendspace in c++

12-23-2016, 07:09 PM
 
Hello all,

i'm trying to automatize the animation of (a lot of) pawns and would like not to have to define ~100 blendspaces and animblueprint by hand in the editor.

If i can get it to work, i'll just have to create blueprints inheriting from this class and set the skeletal mesh and animations.

This subject seems to pop up every now and then, there are a few post on the answerhub, and even a wiki by Rama, but all of them seem to assume that the BlendSpace is created in the editor.

As you can see, i'm trying several methods (via the skeletal mesh component and the anim instance) to animate the mesh with the blendspace, none of them works so far.
I tried everything i could find related to animation and blendspace in the api documentation.

I can spawn the blueprint, but the mesh remains static so obviously i miss something.

I tried to set this in the blueprint, and i can see the debuging flow correctly going through everything.

I can't check visually the blendspace, so i'm a bit lost and dry now.

Here's the code:

void AYagPawn::BeginPlay()
{
Super::BeginPlay(); [...] // creating the BS (SMC_00 is a USkeletalMeshComponent)
ThisBlendSpace1D = NewObject<UBlendSpace1D>(this, UBlendSpace1D::StaticClass());
ThisBlendSpace1D->SetSkeleton(SMC_00->SkeletalMesh->Skeleton); // setting a parameter for the BS
FBlendParameter BP_Speed;
BP_Speed.DisplayName = "Speed";
BP_Speed.GridNum = ;
BP_Speed.Min = .f;
BP_Speed.Max = .f;
ThisBlendSpace1D->UpdateParameter(, BP_Speed); // adding two sample (at 0 and 100)
// IdleSequence and MoveSequence are UAnimSequence to be set in the BP inheriting this pawn class
FBlendSample IdleSample = FBlendSample(IdleSequence, FVector(.f, .f, .f), false);
FBlendSample MoveSample = FBlendSample(MoveSequence, FVector(.f, .f, .f), false);
ThisBlendSpace1D->AddSample(IdleSample);
ThisBlendSpace1D->AddSample(MoveSample); // first method
SMC_00->PlayAnimation(ThisBlendSpace1D, true); // second method
SMC_00->SetAnimation(ThisBlendSpace1D);
SMC_00->Play(true); // third method
SMC_00->OverrideAnimationData(ThisBlendSpace1D, true, true, .f, .f); // fourth method
BS_AnimInstance = Cast<UAnimSingleNodeInstance>(SMC_00->GetAnimInstance());
BS_AnimInstance->SetAnimationAsset(ThisBlendSpace1D);
BS_AnimInstance->PlayAnim(true, .f, .f);
} void AYagPawn::Tick( float DeltaSeconds)
{
Super::Tick(DeltaSeconds); [...] // update BS with Speed (a float)
BS_AnimInstance->SetBlendSpaceInput(FVector(Speed, .f, .f)); // useless in principle but i tried
SMC_00->OverrideAnimationData(ThisBlendSpace1D, true, true, .f, .f);
}

And here is the variables section in the BP:

As you can see, the BS is still empty (normal, it will be created in the begin play function at runtime) and both animations have default values.

Any idea ?

Thanks

Cedric

EDIT: i realized i wasn't setting the animation mode, so i added this in the constructor:

Code:
SMC_00->SetAnimationMode(EAnimationMode::AnimationSingleNode);

But it still doesn't work.

Answers:

Edit: I should have read your entire question. I'm interested in this so I'm going to help you get the bottom of it! You're probably missing an update call somewhere, or you need to serialize the result to an asset or something. I'll report back.

Here's a compiled simple animation blueprint. It uses a blendspace called "Strafe_IP" and has two variables: Right, Forward. Note that the Character class doesn't appear to call or update the animation - it only sets it initially.

Code:
UCLASS(config=Engine, Blueprintable, BlueprintType, meta=(ReplaceConverted="/Game/Blueprints/BPA_Test.BPA_Test_C", OverrideNativeName="BPA_Test_C"))
class UBPA_Test : public UAnimInstance
{
public:
GENERATED_BODY() UPROPERTY(meta=(OverrideNativeName="AnimGraphNode_Root_6D3BF226443B80030387A5AADD092A5D"))
FAnimNode_Root Root; UPROPERTY(meta=(OverrideNativeName="AnimGraphNode_BlendSpacePlayer_44691A814B28B34EF79F7B8F71402E07"))
FAnimNode_BlendSpacePlayer BlendSpacePlayer; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta=(DisplayName="Right", Category="Default", OverrideNativeName="Right"))
float Right; UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta=(DisplayName="Forward", Category="Default", OverrideNativeName="Forward"))
float Forward; UBPA_Test(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
static void __CustomDynamicClassInitialization(UDynamicClass* InDynamicClass);
static void __StaticDependencies_CommonAssets(TArray<FBlueprintDependencyData>& AssetsToLoad);
};
UBPA_Test::UBPA_Test(const FObjectInitializer& ObjectInitializer) : Super()
{
if(HasAnyFlags(RF_ClassDefaultObject) && (UBPA_Test::StaticClass() == GetClass()))
UBPA_Test::__CustomDynamicClassInitialization(CastChecked<UDynamicClass>(GetClass())); Root.Result.LinkID = ;
BlendSpacePlayer.BlendSpace = CastChecked<UBlendSpaceBase>(CastChecked<UDynamicClass>(UBPA_Test::StaticClass())->UsedAssets[], ECastCheckedType::NullAllowed);
BlendSpacePlayer.EvaluateGraphExposedInputs.CopyRecords = TArray<FExposedValueCopyRecord> ();
BlendSpacePlayer.EvaluateGraphExposedInputs.CopyRecords.AddUninitialized();
FExposedValueCopyRecord::StaticStruct()->InitializeStruct(BlendSpacePlayer.EvaluateGraphExposedInputs.CopyRecords.GetData(), ); auto& _Right = BlendSpacePlayer.EvaluateGraphExposedInputs.CopyRecords[];
_Right.SourcePropertyName = FName(TEXT("Right"));
_Right.DestProperty = FindFieldChecked<UFloatProperty>(FAnimNode_BlendSpacePlayer::StaticStruct(), TEXT("X"));
_Right.Size = ; auto& _Forward = BlendSpacePlayer.EvaluateGraphExposedInputs.CopyRecords[];
_Forward.SourcePropertyName = FName(TEXT("Forward"));
_Forward.DestProperty = FindFieldChecked<UFloatProperty>(FAnimNode_BlendSpacePlayer::StaticStruct(), TEXT("Y"));
_Forward.Size = ; Right = 0.000000f;
Forward = 0.000000f;
} void UBPA_Test::__CustomDynamicClassInitialization(UDynamicClass* InDynamicClass)
{
ensure( == InDynamicClass->ReferencedConvertedFields.Num());
ensure( == InDynamicClass->MiscConvertedSubobjects.Num());
ensure( == InDynamicClass->DynamicBindingObjects.Num());
ensure( == InDynamicClass->ComponentTemplates.Num());
ensure( == InDynamicClass->Timelines.Num());
ensure(nullptr == InDynamicClass->AnimClassImplementation); InDynamicClass->AssembleReferenceTokenStream();
FConvertedBlueprintsDependencies::FillUsedAssetsInDynamicClass(InDynamicClass, &__StaticDependencies_DirectlyUsedAssets); auto AnimClassData = NewObject<UAnimClassData>(InDynamicClass, TEXT("AnimClassData"));
AnimClassData->TargetSkeleton = CastChecked<USkeleton>(CastChecked<UDynamicClass>(UBPA_Test::StaticClass())->UsedAssets[], ECastCheckedType::NullAllowed);
AnimClassData->RootAnimNodeIndex = ;
AnimClassData->RootAnimNodeProperty = InDynamicClass->FindStructPropertyChecked(TEXT("Root"));
AnimClassData->AnimNodeProperties = TArray<UStructProperty*> ();
AnimClassData->AnimNodeProperties.Reserve();
AnimClassData->AnimNodeProperties.Add(InDynamicClass->FindStructPropertyChecked(TEXT("Root")));
AnimClassData->AnimNodeProperties.Add(InDynamicClass->FindStructPropertyChecked(TEXT("BlendSpacePlayer")));
InDynamicClass->AnimClassImplementation = AnimClassData;
} void UBPA_Test::__StaticDependencies_CommonAssets(TArray<FBlueprintDependencyData>& AssetsToLoad)
{
const TCHAR* __Local__3 = TEXT("/Game/MovementAnimsetPro/BlendSpaces");
const TCHAR* __Local__4 = TEXT("/Game/Mannequin/Character/Mesh");
FBlueprintDependencyData LocAssets[] =
{
FBlueprintDependencyData(__Local__3, TEXT("Strafe_IP"), TEXT("Strafe_IP"), TEXT("/Script/Engine"), TEXT("BlendSpace")),
FBlueprintDependencyData(__Local__4, TEXT("UE4_Mannequin_Skeleton"), TEXT("UE4_Mannequin_Skeleton"), TEXT("/Script/Engine"), TEXT("Skeleton")),
};
for(auto& LocAsset : LocAssets) { AssetsToLoad.Add(LocAsset); }
} struct FRegisterHelper__UBPA_Test
{
FRegisterHelper__UBPA_Test()
{
FConvertedBlueprintsDependencies::Get().RegisterClass(TEXT("/Game/Blueprints/BPA_Test"), &UBPA_Test::__StaticDependenciesAssets);
}
static FRegisterHelper__UBPA_Test Instance;
}; FRegisterHelper__UBPA_Test FRegisterHelper__UBPA_Test::Instance;

Creating and using a blendspace in c++的更多相关文章

  1. 【解决方案】 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userHandler': Injection of resource dependencies failed;

    一个错误会浪费好多青春绳命 鉴于此,为了不让大家也走弯路,分享解决方案. [错误代码提示] StandardWrapper.Throwableorg.springframework.beans.fac ...

  2. 如何在ASP.NET Web站点中统一页面布局[Creating a Consistent Layout in ASP.NET Web Pages(Razor) Sites]

    如何在ASP.NET Web站点中统一页面布局[Creating a Consistent Layout in ASP.NET Web Pages(Razor) Sites] 一.布局页面介绍[Abo ...

  3. 启用SQLite的Data Provider 运行WECOMPANYSITE时遇到ERROR CREATING CONTEXT 'SPRING.ROOT': ERROR THROWN BY A DEPENDENCY OF OBJECT 'SYSTEM.DATA.SQLITE'

    从网上下载的源码WeCompanySite,运行时报错 Error creating context 'spring.root': Error thrown by a dependency of ob ...

  4. Creating a Clean, Minimal-Footprint ASP.NET WebAPI Project with VS 2012 and ASP.NET MVC 4

    Creating a Clean, Minimal-Footprint ASP.NET WebAPI Project with VS 2012 and ASP.NET MVC 4 Building O ...

  5. Creating a SharePoint Sequential Workflow

    https://msdn.microsoft.com/en-us/library/office/hh824675(v=office.14).aspx Creating a SharePoint Seq ...

  6. [bigdata] 启动CM出现 “JDBC Driver class not found: com.mysql.jdbc.Driver” 以及“Error creating bean with name 'serverLogFetcherImpl'”问题的解决方法

    问题:“JDBC Driver class not found: com.mysql.jdbc.Driver”  通过以下命令启动cm [root@hadoop1 ~]# /etc/init.d/cl ...

  7. 【安卓】aidl.exe E 10744 10584 io_delegate.cpp:102] Error while creating directories: Invalid argument

    这几天在使用.aidl文件的时候eclipse的控制台总是爆出如下提示: aidl.exe E 10744 10584 io_delegate.cpp:102] Error while creatin ...

  8. Failed creating java D:/jre6/bin/client/jvm.dll

    Failed creating java D:/jre6/bin/client/jvm.dll 标记一下 坑爹啊! 我特么装了一个64位的eclipse 结果报错 目录下确实有这个文件. 我想说  6 ...

  9. Spring 异常:Error creating bean with name

    异常信息:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xxx' 我今 ...

随机推荐

  1. swift4.0 数据转模型

    swift 4.0时代的到来,说明了swift已经趋于稳定了,已经完全可以入坑了. 下面就拿最简单的数据转模型来说说,实战一下. 接口使用:  http://116.211.167.106/api/l ...

  2. iOS利用xcodebuild命令自动打包方法

    1,xcode项目先打包试一下可以打包成功 2,创建一plist导出文件 3,xcodebuild命令直接运行 导出文件内容: <?xml version="1.0" enc ...

  3. redis命令Map类型(五)

    如果存储一个对象 这个时候使用String 类型就不适合了,如果在String中修改一个数据的话,这就感到烦琐. hash 散列类型 ,他提供了字段与字段值的映射,当时字段值只能是字符串类型 命令: ...

  4. (转)es6中object.create()和object.assign()

    今天学习javascript面向对象,在学习Obejct方法时了解到create方法,偶像想起之前使用的assign方法,顺带查找一番,感觉这篇博客讲解详细,遂转载. 先简单提一下装饰器函数,许多面向 ...

  5. [LeetCode&Python] Problem 703. Kth Largest Element in a Stream

    Design a class to find the kth largest element in a stream. Note that it is the kth largest element ...

  6. Fiddler实现手机抓包——小白入门

    方法1:https://www.cnblogs.com/hzg1981/p/5610530.html 方法2:转载自:http://blog.csdn.net/gld824125233/article ...

  7. java语言入门

    Java语言的介绍: Java是一种可以撰写跨平台应用程序的面向对象的程序设计语言. 它最初被命名为Oak,目标设定在家用电器等小型系统的编程语言,来解决诸如电视机.电话.闹钟.烤面包机等家用电器的控 ...

  8. 51单片机---点亮一个LED灯

    1 程序源码 #include <REGX52.H> `包含51单片机的头文件` sbit led = P0^0; int main(void) { while(1) { led = 1; ...

  9. 关于python的创立模块和导入

    首先,模块就是所有的.py文件,而模块的作用便是简化代码,使其看得简易. 例如这就是模块: 'a test'这是注释,并没有什么作用. 而创立模块的第一步:建立一个.py文件例如:这是上方这串代码的模 ...

  10. spring-aop思想实践demo

    需求: 例如我们需要有一个类中每个方法执行前都需要做一个权限校验,必须是有特定权限的账号才能完成该方法的操作. 解决方案: 1.使用父类继承方式,书写该类的父类,然后在父类中定义一个checkPri的 ...