UE4:扩展Sequencer的BakeTransform有关Camera的参数

前言

这是之前帮忙做的一点东西,拿来水一下

TA大佬在使用LevelSequence的时候需要Bake一些轨道来导出,其中Camera有部分参数UE本身没有支持Bake,需要进行扩充

问题

FSequencer::BakeTransform()函数中

1
2
3
4
5
6
7
struct FBakeData
{
TArray<FVector> Locations;
TArray<FRotator> Rotations;
TArray<FVector> Scales;
TArray<FFrameNumber> KeyTimes;
};

以上结构体就是Bake的数据,可以看到是Actor通用的数据,但是需要FOV等摄像机用的数据,需要扩充

解决方法

由于这是编辑器方法,那么就直接往里塞啊!简单高效(指解决问题)

首先修改结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
struct FBakeData
{
TArray<FVector> Locations;
TArray<FRotator> Rotations;
TArray<FVector> Scales;
// 增加需要的摄像机参数
TArray<float> Fovs;
TArray<float> FocusDistances;
TArray<float> CurrentAperture;
TArray<float> CurrentFocalLength;
// ......
TArray<FFrameNumber> KeyTimes;
};

紧接着上面这个struct,有一行

1
TMap<FGuid, FBakeData> BakeDataMap;

后面在判断了CameraComponent是否有效之后,会根据情况来向TMap添加数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
if (CameraComponent)
{
FTransform AdditiveOffset;
float AdditiveFOVOffset;
CameraComponent->GetAdditiveOffset(AdditiveOffset, AdditiveFOVOffset);

FTransform Transform(Actor->GetActorRotation(), Actor->GetActorLocation());
FTransform TransformWithAdditiveOffset = AdditiveOffset * Transform;
FVector LocalTranslation = TransformWithAdditiveOffset.GetTranslation();
FRotator LocalRotation = TransformWithAdditiveOffset.GetRotation().Rotator();

BakeDataMap[Guid].Locations.Add(LocalTranslation);
BakeDataMap[Guid].Rotations.Add(LocalRotation);
BakeDataMap[Guid].Scales.Add(FVector::OneVector);
// 在这里,首先确认CameraComponent存在,然后就可以去获取UCineCameraComponent进而拿到摄像机的属性
if (UCineCameraComponent* CineCamera = Cast<UCineCameraComponent>(CameraComponent))
{
BakeDataMap[Guid].Fovs.Add(CineCamera->GetHorizontalFieldOfView());
BakeDataMap[Guid].FocusDistances.Add(CineCamera->FocusSettings.ManualFocusDistance);
BakeDataMap[Guid].CurrentAperture.Add(CineCamera->CurrentAperture);
BakeDataMap[Guid].CurrentFocalLength.Add(CineCamera->CurrentFocalLength);
}
// ......
}
else
{
BakeDataMap[Guid].Locations.Add(Actor->GetActorLocation());
BakeDataMap[Guid].Rotations.Add(Actor->GetActorRotation());
BakeDataMap[Guid].Scales.Add(Actor->GetActorScale());
// 这里是没有摄像机Component的,给默认值
BakeDataMap[Guid].Fovs.Add(0.f);
BakeDataMap[Guid].FocusDistances.Add(0.f);
BakeDataMap[Guid].CurrentAperture.Add(0.f);
BakeDataMap[Guid].CurrentFocalLength.Add(0.f);
// ......
}

在上面这一步给TMap填充完数据之后,就执行转换逻辑,生成float track

这里太长了就不直接放源码了……

主要思路:

  1. 通过FocusedMovieScene获取FMovieSceneBinding,再通过FMovieSceneBinding的GetTracks获取TArray<UMovieSceneTrack*>
  2. 对获取到的Tracks遍历,判断能否Cast为UMovieSceneFloatTrack,且Track不为空
  3. 通过转换得到的UMovieSceneFloatTrack的UniqueTrackName确认是摄像机的哪一个属性
  4. 创建一个新的UMovieSceneFloatTrack,因为可能需要保留原来的Track
  5. 对新创建的NewFloatTrack,调用SetPropertyNameAndPath设置属性
  6. 创建一个UMovieSceneFloatSection,将其添加到NewFloatTrack
  7. 对UMovieSceneFloatSection进行SetRange,对Section的Channels进行SetDefault,这里一般只会用到Channels[0]
  8. 最后对BakeData.Value.KeyTimes遍历,对FloatChannels进行AddLinearKey

搞定!


UE4:扩展Sequencer的BakeTransform有关Camera的参数
http://muchenhen.com/posts/50458/
作者
木尘痕
发布于
2022年8月15日
许可协议