转自: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. JPype1使用总结

    目的:使用Locust+Python压测账号资料接口,使用JPype调用java代码,缩短压测脚本编写 前提条件:进行性能压测过程中,需要压测账号相关接口,由于账号相关接口设计到加密解密,用Pytho ...

  2. Struts2 前台显示问题

    遇到的问题: 查询字段相同值的和的时候用到了sum函数,导致和实体类的不一样,无法取到. 开始的时候的代码. ; 这样的话SUM(o_count)无法显示. 我想把SUM(o_count)设置为实体类 ...

  3. phpstorm快捷键总结

    如果映射的是eclipse的快捷键,又同时安装了英特尔的GPU软件,那么会有这个快捷键冲突 就是快速复制快捷键:ctrl+alt+方向键  会调用英特尔旋转屏幕,禁用掉即可 PhPStorm 是 Je ...

  4. 往redis中存储数据是利用pipeline方法

    在redis中保存数据时,保存和设置有效时间是分开写的话,如果中间出现的异常,这会导致数据永久有效,因此就可以采用pipeline方法. # 创建redis管道对象,可以一次执行多个语句 pipeli ...

  5. LR-SVM(有待重新整理)

    参考:http://www.zhihu.com/question/26768865 总结: 1)在线学习:SVM不支持在线学习,LR支持 2)不平衡数据:SVM不依赖于数据的分布,所以数据是否平衡影响 ...

  6. 20175120彭宇辰 《Java程序设计》第七周学习总结

    #教材内容总结 第八章 常用实用类 一.String类 String类用来处理字符序列,在java.lang包中,程序可以直接使用String类.需要注意的是Java把String类声明为final类 ...

  7. xxxx征集系统项目目标文档

    分组:每四人一组 主题:xxx征集系统 成果: 讨论结束后,每组提交一份课堂讨论记录(电子版发表到博客上,纸质版小组成员签名,下节课提交). 每人根据课堂讨论结果提交一份系统利益相关者描述案例.撰写项 ...

  8. 一个简单springboot搭建

    首先,新建一个maven项目,new maven project 然后打开pom.xml,引入需要的jar包,代码如下: <parent> <groupId>org.sprin ...

  9. python 多进程的两种创建方式

    Python中使用线程有两种方式:函数或者用类来包装线程对象. 第一种---------函数 菜鸟教程的我没看懂,说说我自己懂的----看视频理解的 import time import thread ...

  10. Oracle深入学习

    一.甲骨文公司介绍 甲骨文公司,是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩.1989年正式进入中国市场. 2013年,甲骨文已超越 IBM ,成为继 Microsoft 后全球第二大 ...