Unreal LevelSequence功能扩展

本文介绍了如何在LevelSequence中扩展Track以支持对话字幕功能,包括创建自定义Track、Section、EvalTemplate和ExecutionToken的过程,以及为何将逻辑分隔处理的原因。
摘要由CSDN通过智能技术生成

前言

使用LevelSequence制作过场动画时如果包含对话又希望使用项目中已有的对话系统来展示UI字幕等效果时,就需要为LevelSequence扩展我们自己的Track等类型,本文就以展示对话字幕这个场景分析下LevelSequence涉及的几个相关类型
在这里插入图片描述

框架分析

MovieSceneTrack

首先我们需要实现一个Track作为字幕轨道就像SkeletonMeshTrack和TransformTrack一样,我们需要继承UMovieSceneTrack,Track并不做实际的工作,我们只需要指定Track的名字以及它能支持的Section类型

	virtual bool SupportsType(TSubclassOf<UMovieSceneSection> SectionClass) const override;
	virtual FName GetTrackName() const override;
#if WITH_EDITORONLY_DATA
	virtual FText GetDisplayName() const override;
#endif

然后最重要的就是我们要实现创建我们自己的Section和EvalTemplate的接口,创建自己的类返回就可以了

virtual UMovieSceneSection* CreateNewSection() override;
virtual FMovieSceneEvalTemplatePtr CreateTemplateForSection(const UMovieSceneSection& InSection) const override;

在创建完Track后就能在Sequencer编辑器的添加轨道中看到我们自己的轨道了。UMovieSceneTrack在编译后会成为FMovieSceneEvaluationTrack用于Runtime的Evaluate

MovieSceneSection

Section就是你在轨道上添加的每个段,简单来说就是一个数据载体,我们需要在自己的Section中通过UPROPERTY将对应的字幕属性(Text或者DataTableRowHandle)暴露给Sequencer编辑器,在运行时访问这些属性进行Evaluate

UCLASS(MinimalAPI)
class UMovieSceneDialogueSection : public UMovieSceneSection
{
private:
	UPROPERTY(EditAnywhere, Category = Dialogue)
		bool bHideDialogueUI = false;

	UPROPERTY(EditAnywhere, Category = Dialogue)
		FDataTableRowHandle DialogueRowHandle;
};

MovieSceneEvalTemplate

EvalTemplate是每个Track在编译时创建出的东西,包含在FMovieSceneEvaluationTrack中,每个EvalTemplate对应一个section(通过前面Track实现的CreateTemplateForSection),所以一个Track可能包含多个EvalTemplate。
EvalTemplate指定了Section的执行方式,由于创建EvalTemplate的函数是我们自己在Track中实现的,所以我们在创建时就可以把Section中配置好的属性给到EvalTemplate

FMovieSceneDialogueTemplate::FMovieSceneDialogueTemplate(const UMovieSceneDialogueSection* InSection)
	: Section(InSection)
{
	UMovieSceneDialogueSection* SectionPtr = const_cast<UMovieSceneDialogueSection*>(InSection);
	if (SectionPtr == nullptr)
	{
		return;
	}

	bHideDialogueUI = SectionPtr->GetShouldHideDialogueUI();
	DialogueRowHandle = SectionPtr->GetDialogueinfoRow();
}

然后我们需要实现几个函数,Setup和Teardown分别是在Section的开始和结束时调用,Evaluate则是每次Tick的执行函数

	virtual void Evaluate(const FMovieSceneEvaluationOperand& Operand, const FMovieSceneContext& Context, const FPersistentEvaluationData& PersistentData, FMovieSceneExecutionTokens& ExecutionTokens) const override;

	virtual UScriptStruct& GetScriptStructImpl() const override { return *StaticStruct(); }

	virtual void Setup(FPersistentEvaluationData& PersistentData, IMovieScenePlayer& Player) const override;
	virtual void TearDown(FPersistentEvaluationData& PersistentData, IMovieScenePlayer& Player) const override;
	virtual void SetupOverrides() override { EnableOverrides(RequiresSetupFlag | RequiresTearDownFlag); }

在Setup和Teardown中我们需要向PersistentData中放入我们自己定义好的Data,供后续Token使用

struct FDialogueEvaluationData : IPersistentEvaluationData
{
		bool bHideDialogueUI = false;
		FDataTableRowHandle DialogueRowHandle;
};
struct FDialogueExecutionToken : IMovieSceneExecutionToken
{
	virtual void Execute(const FMovieSceneContext& Context, const FMovieSceneEvaluationOperand& Operand,
		FPersistentEvaluationData& PersistentData, IMovieScenePlayer& Player) override
	{
		auto persistentData = PersistentData.GetSectionData<FDialogueEvaluationData>();
		//Do Logic Here
	}
};

在Evaluate中只需要将我们自己的Token加入TokenStack中即可

void FMovieSceneDialogueTemplate::Evaluate(const FMovieSceneEvaluationOperand& Operand, const FMovieSceneContext& Context,
	const FPersistentEvaluationData& PersistentData, FMovieSceneExecutionTokens& ExecutionTokens) const
{
	ExecutionTokens.Add(FDialogueExecutionToken());
}

那么这里其实就有一个问题,我们为什么不直接在Evaluate中执行逻辑使用EvalTemplate中的成员变量,而要把数据先放到EvaluationData中再通过Token来执行逻辑呢?
区别在于Evaluate本身不一定执行在GameThread上,为了效率可以将一些耗时性的计算工作放在Evaluate中;而Token的Execute是一定执行在GameThread上的,由于我们要通过事件等方式驱动我们的UI显示对话文本,所以我们的逻辑需要放在Token中,数据自然也要放到EvaluationData中。

总结

Track、Section、EvalTemplate、EvaluationData和ExecutionToken就是我们在扩展轨道时需要接触的几个概念,我们不仅可以显示对话文本,如果我们有对话选项等系统的话也可以按照相同的方式与Sequence结合起来,更好的将Sequence融入到游戏中
关于更加详细的源码分析可以参考其他大佬的文章
UE4 LevelSequence源码剖析(一)
UE4 LevelSequence源码剖析(二)
UE4 LevelSequence源码剖析(三)

  • 28
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值