【UE4】通过动画序列自动生成蒙太奇(In Code)
本文使用 UE4.26 版本,ActionRPG 教程为例,通过代码实现通过动画序列自动生成蒙太奇的功能。
包括:
- 批量通过动画生成对应蒙太奇(UE4 自带,但是需要改)
- 通过多个动画拼成一个蒙太奇,并设置对应的 Sections
一、功能背景
1.1 需求和场景
- 很多动画蒙太奇(AM)是直接通过动画序列(A),在 Content 目录下直接右键新建蒙太奇生成的,不需要有什么修改,理论应该可以批量生成
- 有些蒙太奇是通过多个 A 拼接而成,其中 Section 的位置以及名字都是固定的(位置和动画对齐,名字固定)
在这种情况下,程序直接批量生成,会大幅提升效率,并提升质量(只要保证动画没错,就不会出现策划配错了的情况),而且策划也懒得配。。
1.2 所需背景知识
只需要很基础的只是,就是蒙太奇上的 Section 和 Slot,以及 Segment 具体是什么,以及是干嘛用的。
UCLASS(config=Engine, hidecategories=(UObject, Length), MinimalAPI, BlueprintType)
class UAnimMontage : public UAnimCompositeBase
{GENERATED_UCLASS_BODY()// composite section. UPROPERTY()TArray<FCompositeSection> CompositeSections;// slot data, each slot contains anim trackUPROPERTY()TArray<struct FSlotAnimationTrack> SlotAnimTracks;
}
上边是蒙太奇类中,这篇文章中关心的两个成员: CompositeSections(简称 Sections)以及 SlotAnimTracks(简称 Slot,主要关心里边的 Segments)。
1.2.1 CompositeSections
下图中三个红框就是三个 Section,这个蒙太奇的 CompositeSections
大小就是 3。
Section 用来把动画分成多段。可以循环,可以跳过等等操作,如下,是技能中,直接跳到蒙太奇某一段的函数:
void UGameplayAbility::MontageJumpToSection(FName SectionName)
{check(CurrentActorInfo);UAbilitySystemComponent* const AbilitySystemComponent = GetAbilitySystemComponentFromActorInfo_Checked();if (AbilitySystemComponent->IsAnimatingAbility(this)){AbilitySystemComponent->CurrentMontageJumpToSection(SectionName);}
}
1.2.2 Slot 和 Segment
下图中,左边这个 Default.Default 是一个 Slot,即这个蒙太奇 SlotAnimTracks
大小是 1(一般就一个 Slot)。
USTRUCT()
struct FSlotAnimationTrack
{GENERATED_USTRUCT_BODY()UPROPERTY(EditAnywhere, Category=Slot)FName SlotName;UPROPERTY(EditAnywhere, Category=Slot)FAnimTrack AnimTrack;
};
一个 Slot 中有一个 AnimTrack
。
USTRUCT()
struct FAnimTrack
{GENERATED_USTRUCT_BODY()UPROPERTY(EditAnywhere, Category=AnimTrack, EditFixedSize)TArray<FAnimSegment> AnimSegments;
}
每个 AnimTrack
中有 AnimSegments
,每个 Segment 中是一段动画,包括动画序列,开始时间,结束时间,在蒙太奇中的开始时间等。
/** this is anim segment that defines what animation and how **/
USTRUCT()
struct FAnimSegment
{GENERATED_USTRUCT_BODY()/** Anim Reference to play - only allow AnimSequence or AnimComposite **/UPROPERTY(EditAnywhere, Category=AnimSegment)UAnimSequenceBase* AnimReference;/** Start Pos within this AnimCompositeBase */UPROPERTY(VisibleAnywhere, Category=AnimSegment)float StartPos;/** Time to start playing AnimSequence at. */UPROPERTY(EditAnywhere, Category=AnimSegment)float AnimStartTime;/** Time to end playing the AnimSequence at. */UPROPERTY(EditAnywhere, Category=AnimSegment)float AnimEndTime;/** Playback speed of this animation. If you'd like to reverse, set -1*/UPROPERTY(EditAnywhere, Category=AnimSegment)float AnimPlayRate;UPROPERTY(EditAnywhere, Category=AnimSegment)int32 LoopingCount;
}
需要注意的是:
- section 的位置不一定需要和每一段动画开头对上,可以在任意位置,不过拖动 Section 靠近动画开头,会有吸力,松手就自动对齐
- Segment 的
StartPos
和AnimStartTime
很容易混淆:
StartPos
- 这一段动画,在整个蒙太奇的什么时间开始AnimStartTime
- 这个 Segment,是从对应的动画的什么时候开始,一般是 0,即从头开始AnimEndTime
- 同上,这个 Segment 播放到动画的什么时候结束,一般是动画长度,即完整播完AnimPlayRate
- 这个 Segment 中动画播放速度,默认1,例如,如果是 2,则这段动画只需要一半时间就两倍速播完LoopingCount
- 这段动画的循环次数,默认 1,如果是0,则这段动画就没了,不是一直循环的意思(一致循环通过 Section 实现)
二、实现效果
三、实现方法
3.1 参考方法
3.1.1 右键生成蒙太奇效果
参考方法就是在 Content 中右键一个动画序列,然后选择 Create -> Create AnimMontage
,的功能,如下图所示:
这样生成的蒙太奇包括一个 Section,叫作 Default
,和一个 Segment,就是选择的动画。
注意:
- 这个右键操作生成的蒙太奇,名称默认为 xx_Montage,xx 是动画资源的名称(如果这个名字的蒙太奇已经有了,则会是 xx_Montage1,以此类推),所以不会出现把原有文件覆盖的问题;
- 这个操作可以批量生成,选十个动画,然后右键生成蒙太奇,就是会生成这十个动画对应的十个蒙太奇,并不会十个动画拼接成一个蒙太奇;
3.1.2 右键生成蒙太奇代码
这种有按钮,有界面的功能,一般直接搜索对应的 Tips 文字就能找到功能,即 Creates an AnimMontage using the selected anim sequence
:
MenuBuilder.AddMenuEntry(LOCTEXT("AnimSequence_NewAnimMontage", "Create AnimMontage"),LOCTEXT("AnimSequence_NewAnimMontageTooltip", "Creates an AnimMontage using the selected anim sequence."),FSlateIcon(FEditorStyle::GetStyleSetName(), "ClassIcon.AnimMontage"),FUIAction(FExecuteAction::CreateSP(this, &FAssetTypeActions_AnimSequence::ExecuteNewAnimMontage, Sequences),FCanExecuteAction()));
即 ExecuteNewAnimMontage
函数,里边调用的就是 FAssetTypeActions_AnimSequence::CreateAnimationAssets
。
/** Creates animation assets of the supplied class */
void CreateAnimationAssets(const TArray<TWeakObjectPtr<UAnimSequence>>& AnimSequences, /* 所选中的动画序列资源,可以是多个 */TSubclassOf<UAnimationAsset> AssetClass, /* 要生成的动画资源类型, 即 - UAnimMontage::StaticClass() */UFactory* AssetFactory, /* 蒙太奇生成工厂 - NewObject<UAnimMontageFactory>() */const FString& InSuffix, /* 生成的资源名称后缀, 默认 - TEXT("_Montage"); */FOnConfigureFactory OnConfigureFactory) const;
这个方法中根据 AnimSequences 的数量分了两部分,一种是只有一个动画资源的,直接生成对应的蒙太奇;一种是有多个动画资源的,生成多个蒙太奇。实际只需要看一个动画的部分:
auto AnimSequence = AnimSequences[0].Get();if ( AnimSequence )
{// Determine an appropriate name for inline-renameFString Name;FString PackageName;CreateUniqueAssetName(AnimSequence->GetOutermost()->GetName(), InSuffix, PackageName, Name);if (OnConfigureFactory.IsBound()){if (OnConfigureFactory.Execute(AssetFactory, AnimSequence)){FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");ContentBrowserModule.Get().CreateNewAsset(Name, FPackageName::GetLongPackagePath(PackageName), AssetClass, AssetFactory);}}
}
其中 CreateUniqueAssetName
是判断生成的资源叫什么名字,默认 xx_Montage,如果有冲突,则 xx_Montage1,实际生成,就是 CreateNewAsset
,上边的 OnConfigureFactory
的用处就是绑定一下动画是哪个。
3.2 实际方法
3.2.1 批量通过动画生成对应蒙太奇
其实 UE 自带的就是这个功能,不需要怎么改,但是由于名字会自动变,如果想生成特定名字,且覆盖原有的话,需要改引擎。
UObject* UAssetToolsImpl::CreateAsset(const FString& AssetName, const FString& PackagePath, UClass* AssetClass, UFactory* Factory, FName CallingContext)
{const FString PackageName = UPackageTools::SanitizePackageName(PackagePath + TEXT("/") + AssetName);// Make sure we can create the asset without conflictsif (!CanCreateAsset(AssetName, PackageName, LOCTEXT("CreateANewObject", "Create a new object")) ){return nullptr;}// 生成资源 blablareturn NewObj;
}
最终生成资源,调到的就是最后这个函数,但是在生成资源之前,会进行是不是 Exist 的检查,如果有,则会弹出消息框,需要点。
UObject* ExistingObject = StaticFindObject( UObject::StaticClass(), Pkg, *AssetName );
if( ExistingObject != nullptr )
{// Object already exists in either the specified package or another package. Check to see if the user wants// to replace the object.bool bWantReplace =EAppReturnType::Yes == FMessageDialog::Open(EAppMsgType::YesNo,EAppReturnType::No,FText::Format(NSLOCTEXT("UnrealEd", "ReplaceExistingObjectInPackage_F", "An object [{0}] of class [{1}] already exists in file [{2}]. Do you want to replace the existing object? If you click 'Yes', the existing object will be deleted. Otherwise, click 'No' and choose a unique name for your new object." ),FText::FromString(AssetName),FText::FromString(ExistingObject->GetClass()->GetName()), FText::FromString(PackageName) ) );
}
消息框自定义可以看这篇。
如果有二十个冲突的蒙太奇,则需要点二十下,如果不想点,就要改引擎,CreateAsset
加个参数 - 要不要考虑冲突,然后直接不检查了。
3.2.2 多个动画拼成一个蒙太奇
多个动画拼接成一个蒙太奇(如 1.2.2 中所示),可以先用一个动画,按照 3.2.1 的方法生成一个蒙太奇,然后调整对应的 CompositeSections以及 SlotAnimTracks 即可。
注意:创建了 Section 之后,需要设置 NextSectionName
,不然只会播一个 Section 的动画;如果希望其中某一段循环,让它的下一段是自己即可:
CompositeSections[3].NextSectionName = CompositeSections[3].SectionName;
四、参考资料
- Animation Montage Overview(官方 docs)
- Introduction to AnimMontage(官方 blog)
【UE4】通过动画序列自动生成蒙太奇(In Code)相关推荐
- 西门子界面官方精美触摸屏+WINCC程序模板 西门子官方触摸屏程序模板,炫酷的扁平式动画效果,脚本动画,自动生成二维码,可仿真,堪比智能手机,有精简,精致,wincc,无线面板等包含了所有西门子人机界
西门子界面官方精美触摸屏+WINCC程序模板 西门子官方触摸屏程序模板,炫酷的扁平式动画效果,脚本动画,自动生成二维码,可仿真,堪比智能手机,有精简,精致,wincc,无线面板等包含了所有西门子人机界 ...
- dm数据库无法用序列自动生成主键,无法解析的成员访问表达式【SEQ_STU_CON_NEXTVAL】
报错信息: 无法解析的成员访问表达式[SEQ_STU_CON_NEXTVAL] select SEQ_STU_CON_NEXTVAL 这种错的解决方案,在dm数据库中创建一个序列叫SEQ_STU_CO ...
- oracle创建表,序列,触发器,自动生成唯一主键
数据库oracle和mysql插入数据的区别? mysql数据库主键字段是increament,则插入数据不需要插入主键字段.数据库会自动生成主键 oracle数据库主键字段必须创建序列,则插入数据必 ...
- UE4(Unreal Engine4)在蒙太奇动画中添加音频轨道通知
UE4系列文章目录 文章目录 UE4系列文章目录 前言 一.遇到的问题 二.操作步骤 前言 UE4(Unreal Engine4)在蒙太奇动画中添加音频轨道通知,我们想在某一帧动画中添加声音.比如我们 ...
- 语音识别插件_2D动画唇动合成,根据语音自动生成动画人物口型
蕾师师 发自 凹非寺 量子位 报道 | 公众号 QbitAI 只需要输入一段语音,代码会自动生成与之相对的动画唇形. 还是毫无违和感的那种. 这是一个在GitHub上拥有501星的开源项目,叫做Rhu ...
- Mockplus Cloud自动生成规格,Mockplus Cloud交互式动画原型
Mockplus Cloud自动生成规格,Mockplus Cloud交互式动画原型 Mockplus Cloud 帮助您连接整个产品设计工作流程,让设计协作更轻松.它可以让您从 Sketch.Ado ...
- [Unity编辑器] 根据图片自动生成动画
根据自己的情况 仿照 雨松MOMO 写了一个自动生成动画的脚本 原地址 http://www.xuanyusong.com/archives/3243 代码: using UnityEngine; u ...
- adobe xd导出html,Adobe XD2018年10月更新,自动生成动画、导出到 After Effects等功能...
Adobe XD 是一款超前且免费的用户体验设计工具,可以轻松完成网站.移动应用程序.语音交互.触摸屏等内容的设计和原型创建,目前保持每月更新一次的节奏,10月的今天,在Adobe MAX 2018到 ...
- 2D动画唇动合成,根据语音自动生成动画人物口型
蕾师师 发自 凹非寺 量子位 报道 | 公众号 QbitAI 只需要输入一段语音,代码会自动生成与之相对的动画唇形. 还是毫无违和感的那种. 这是一个在GitHub上拥有501星的开源项目,叫做Rhu ...
最新文章
- List嵌套List数据,全部List数组一起更新问题
- Raspberry Zero 上实现平滑视频图传
- 函数和闭包之头等函数
- Spring Boot spring mvc 拦截器
- 关于redis的文章
- jQuery 插件 Validation表单验证 使用步骤(详细的)
- CSS深入理解学习笔记之vertical-align
- Linux 命令(94)—— env 命令
- Jquery事件委托之Safari
- python32位 最大内存_64位windows上的Python 32位内存限制
- 在OSPF网络中,如何判断LSA的新旧?
- nginx做负载均衡+keepalived(做主备)
- CONVERT TEXT(转换为可排序格式)
- 高质量Python书籍推荐丨Python学习手册(第5版)
- LU分解算法(串行、并行)
- 企业微信员工离职后,还能看聊天记录吗?
- 推荐21个高质量图片网站,免费免版权,值得收藏
- python bytes
- cookie用法--抽屉网的自动登录(cookie是通过代码自动获取的)
- 微信扫付款后,付错款,不是好友也能联系到收款方