Java教程

动画 - 记录蒙太奇的几个误区 - 心意不定的UE4随笔录

本文主要是介绍动画 - 记录蒙太奇的几个误区 - 心意不定的UE4随笔录,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

记录UE4 蒙太奇的几个误区

目录
  • 记录UE4 蒙太奇的几个误区
    • 现象
      • 1. 同一时刻一个slot只能有一个蒙太奇在播放
      • 2. StopAllMontage 会终止所有正在播放的蒙太奇

一不小心就暴露了自己的知识水平

现象

1. 同一时刻一个slot只能有一个蒙太奇在播放

在没有深入了解蒙太奇这方面的原理前,一直都以为播放一个蒙太奇时会将其所占据的所有slot上正在播放的其他蒙太奇给终止掉。

可以用一个及其简单的例子来证明这个是错误的:

image-20220424231345697

如图AnimGraph, SlotNode 直接连接输出节点。

image-20220424232005017

接着,在EventGraph中的初始化函数中调用Montage_Play接口,任意选取一个蒙太奇,将PlayRate调小方便观看,并取消勾选 StopAllMontages 选项。

此时点击编译,会发现十分正常的播放了这个蒙太奇。

image-20220424232351189

继续添加类似节点,并选取一个与先前的蒙太奇差异较大的资源,再次点击编译。

image-20220424232452546

你会发现两个蒙太奇被混合到了一起。

具体代码可以参考 FAnimInstanceProxy::SlotEvaluatePose 函数:

// 遍历所有执行中的蒙太奇数据 将所有包含指定的slot的蒙太奇进行收集
for (const FMontageEvaluationState& EvalState : MontageEvaluationData)
{
	const UAnimMontage* const Montage = EvalState.Montage.Get();
	if (Montage->IsValidSlot(SlotNodeName))
	{
		if (AdditiveAnimType == AAT_None)
		{
			NonAdditivePoses.Add(FSlotEvaluationPose(MoveTemp(NewPose)));
		}
		else
		{
			AdditivePoses.Add(FSlotEvaluationPose(MoveTemp(NewPose)));
		}
	}
}

// ...
// 获取所有非additive动画的Pose以及权重
int32 const NumPoses = NonAdditivePoses.Num() + ((SourceWeight > ZERO_ANIMWEIGHT_THRESH) ? 1 : 0);
BlendingPoses.AddUninitialized(NumPoses);
BlendWeights.AddUninitialized(NumPoses);
for (int32 Index = 0; Index < NonAdditivePoses.Num(); Index++)
{
	BlendingPoses[Index] = &NonAdditivePoses[Index].Pose;
	BlendWeights[Index] = NonAdditivePoses[Index].Weight;
}
// 如果有Source节点(即SlotNode连接的输入节点)
// 则也记录其Pose以及权重
if (SourceWeight > ZERO_ANIMWEIGHT_THRESH)
{
	int32 const SourceIndex = BlendWeights.Num() - 1;
	BlendingPoses[SourceIndex] = &SourcePose;
	BlendWeights[SourceIndex] = SourceWeight;
}

// 对收集来的数据进行混合
FAnimationRuntime::BlendPosesTogetherIndirect(BlendingPoses, BlendingCurves, BlendingAttributes, BlendWeights, OutBlendedAnimationPoseData);

2. StopAllMontage 会终止所有正在播放的蒙太奇

之前使用 Montage_Play 函数播放蒙太奇时,有一个 StopAllMontage 参数,在之前我对这个参数存在了一个非常能自圆其说的误解,总结如下:

  • 使用 StopAllMontage 是将除了该蒙太奇以外的所有蒙太奇终止掉。

事实上,该参数为true时,只会终止蒙太奇占用的第一个Track的Slot所在的Group内的其他蒙太奇。

可以参考 UAnimInstance::Montage_Play :

if (bStopAllMontages)
{
	FName NewMontageGroupName = MontageToPlay->GetGroupName();
	StopAllMontagesByGroupName(NewMontageGroupName, MontageToPlay->BlendIn);
}

但是这里有一点比较违反直觉(虽然这参数叫StopAllMontages就已经很违反直觉了),因为蒙太奇其实可以有多个slot,为什么这里不将所有的slot的group给终止掉呢?

image-20220424235253523

好吧,原来是生成蒙太奇资产的时候就规定了,所有track的slot必须在同一个group下。

仔细一想其实也是合理的,因为既然是同一个蒙太奇,里面不同的track理当是同一种类型的动画才对。

这篇关于动画 - 记录蒙太奇的几个误区 - 心意不定的UE4随笔录的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!