[ue4] 360 度ステレオ動画を作る


#【前提】
__・ue4を使用して360度ステレオ動画を作ってみたワークフローの備忘録です。__
__・うそを書くつもりはありませんが。経験に基づいて記述しているため、間違いが多分にある可能性があります。__
__・Windowsを使用しているため、説明文の特殊キーやマウスは、他の環境の場合は読み替えてください。__
__・ue4.11.2を使用しています。プラグインのソース修正が必要なため、私の場合は個別にエンジンをビルドし直しています。__
__・Epicさんの公式サイトで説明されていますが、「なるほどわからん」だったので色々調べた結果を記述してます。__
↓公式さんの解説記事です。
https://www.unrealengine.com/ja/blog/capturing-stereoscopic-360-screenshots-videos-movies-unreal-engine-4


#【目的】
UE4で360度ステレオ動画を作る手順です。

__※注意：全てのURLリンクを開くときは、マウスの左クリックで「新しいタブで開く」で開いてください。__
__また、画像が小さくて見づらい場合は画像をクリックしてください。__

#【プラグインのソース修正】

使用するプラグインはこの「Stereo Panoramic Movie Capture」です。

![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/84be29e0-c05a-43c0-3d5e-ab84b7a3bad7.jpeg)

これのソースを改造することになるわけですが。
私の場合、製品版の（ランチャーから起動する）ue4を改造したくなかったのでEpicさんのGitHubからue4.11.2のソースをダウンロードしてきて修正しました。

エンジンの個別ビルド辺りは、解説しているサイトが沢山あるので割愛します。

さて、プラグインを修正するわけですが。
ソースはここのSceneCapturer.cppです。

![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/ad7205f6-a7a0-88df-36c5-9b928e9effa8.jpeg)

ここは公式さんで解説されているとおり修正します。

４か所修正します。

１）グローバル変数でフラグを作成


```SceneCapturer.cpp
const bool CombineAtlasesOnOutput = true;
```

グローバル変数なのでどこでも問題ないと思いますが
私はここに書きました。

![3.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/256d69c4-b9de-fbb1-e2a7-94aa813143a4.jpeg)

２）フラグによる制御
次に上記のフラグによる制御の追加

```SceneCapturer.cpp
TArray<FColor> USceneCapturer::SaveAtlas(FString Folder, const TArray<FColor>& SurfaceData)
```
のメソッド内部を２か所修正します。

620行目あたりを既存の処理を先ほど追加したグローバルなフラグで制御するためif分で括ります。

![4.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/e5b13834-2115-7336-d26f-258ebc1f4780.jpeg)


```SceneCapturer.cpp
	if (!CombineAtlasesOnOutput) //*NEW* - Don't do this here if we're going to combine them. (結合するつもりであれば、これを行わないでください)

	{
    ImageWrapper->SetRaw(SphericalAtlas.GetData(), SphericalAtlas.GetAllocatedSize(), SphericalAtlasWidth, SphericalAtlasHeight, ERGBFormat::BGRA, 8);
	const TArray<uint8>& PNGData = ImageWrapper->GetCompressed(100);
	FFileHelper::SaveArrayToFile( PNGData, *AtlasName );
	}
```

３）PNGDataからPNGDataUnprojectedに変更
次に上記修正を加えるとPNGDataの部分で以下がエラーになるのでPNGData部分を、PNGDataUnprojectedに変更します。

![5.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/8891a1c7-8e48-40de-fab2-055f94439a81.jpeg)

```SceneCapturer.cpp
if (FStereoPanoramaManager::GenerateDebugImages->GetInt() != 0)
{
    FString FrameStringUnprojected = FString::Printf(TEXT("%s_%05d_Unprojected.png"), *Folder, CurrentFrameCount);
    FString AtlasNameUnprojected = OutputDir / Timestamp / FrameStringUnprojected;

    ImageWrapper->SetRaw(SurfaceData.GetData(), SurfaceData.GetAllocatedSize(), UnprojectedAtlasWidth, UnprojectedAtlasHeight, ERGBFormat::BGRA, 8);
    const TArray<uint8>& PNGDataUnprojected = ImageWrapper->GetCompressed(100);
//       FFileHelper::SaveArrayToFile(PNGData, *AtlasNameUnprojected);
        FFileHelper::SaveArrayToFile(PNGDataUnprojected, *AtlasNameUnprojected);
}
ImageWrapper.Reset();
```

最後に一か所

```SceneCapturer.cpp
void USceneCapturer::Tick( float DeltaTime )
```
の以下の部分を修正します。
![6.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/9aa4ea68-f1f7-f849-1bbd-7254fa81fc08.jpeg)

```SceneCapturer.cpp
	else
	{
		TArray<FColor> SphericalLeftEyeAtlas  = SaveAtlas( TEXT( "Left" ), UnprojectedLeftEyeAtlas );
        TArray<FColor> SphericalRightEyeAtlas = SaveAtlas(TEXT("Right"), UnprojectedRightEyeAtlas);
		//*NEW* - Begin (開始)

		if (CombineAtlasesOnOutput)

		{

			TArray<FColor> CombinedAtlas;

			CombinedAtlas.Append(SphericalLeftEyeAtlas);

			CombinedAtlas.Append(SphericalRightEyeAtlas);

			IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::JPEG);

			ImageWrapper->SetRaw(CombinedAtlas.GetData(), CombinedAtlas.GetAllocatedSize(), SphericalAtlasWidth, SphericalAtlasHeight * 2, ERGBFormat::BGRA, 8);

			const TArray<uint8> &PNGData = ImageWrapper->GetCompressed(100);

			// Generate name (名前を生成します)。

			FString FrameString = FString::Printf(TEXT("Frame_%05d.jpg"), CurrentFrameCount);

			FString AtlasName = OutputDir / Timestamp / FrameString;

			FFileHelper::SaveArrayToFile(PNGData, *AtlasName);

			ImageWrapper.Reset();

		}
		// Dump out how long the process took
		FDateTime EndTime = FDateTime::UtcNow();
		FTimespan Duration = EndTime - StartTime;
		UE_LOG( LogStereoPanorama, Log, TEXT( "Duration: %g seconds for frame %d" ), Duration.GetTotalSeconds(), CurrentFrameCount );
		StartTime = EndTime;
```

さて修正が終わったらエンジンをビルドしてコンパイルします。
ビルドが完了したら次に進みます。
ビルドでなんらかのエラーが出たらもう一度プラグインのソースを見直してみてください。

#【プラグインの有効化】

![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/0910c188-70bf-7387-1656-eddde67ed0a4.jpeg)

エディタのプラグイン設定で「Stereo Panoramic Movie Capture」を有効化します。

#【コンソールコマンド発行】

ue4のエディタのコンソール部分で以下のコマンドを叩きます。

SP.OutputDir __G:/StereoCaptureFrames__
↑太字部分が最終的にレンダリングした連番画像を出力するフォルダです

SP.HorizontalAngularIncrement 2

SP.VerticalAngularIncrement 30

SP.CaptureHorizontalFOV 30

SP.ConcurrentCaptures 6

SP.CaptureSlicePixelWidth 720

SP.ShouldOverrideInitialYaw 0

以下は出力する解像度によって違いますが私は

SP.StepCaptureWidth 4096

としました。

もっと高解像度の場合は

SP.StepCaptureWidth 6144

でも良いみたいです。

ということなのですが。これを毎度毎度打つのはきついのでblueprint化します。


![image](https://qiita-image-store.s3.amazonaws.com/0/59114/cfa9319f-7e7e-4b3f-2dd0-7458bf37d348.png)


以下のテキストをレベルブループリントにコピペすれば行けると思います。

```BluePrint
Begin Object Class=K2Node_CallFunction Name="K2Node_CallFunction_2505"
   Begin Object Class=EdGraphPin Name="EdGraphPin_5089"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5090"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5091"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5092"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5093"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5094"
   End Object
   Begin Object Name="EdGraphPin_5089"
      PinName="execute"
      PinToolTip="\n実行"
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_Event_390.EdGraphPin_4715'
   End Object
   Begin Object Name="EdGraphPin_5090"
      PinName="then"
      PinToolTip="\n実行"
      Direction=EGPD_Output
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2506.EdGraphPin_5107'
   End Object
   Begin Object Name="EdGraphPin_5091"
      PinName="self"
      PinFriendlyName="ターゲット"
      PinToolTip="ターゲット\nKismet System Library リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.KismetSystemLibrary')
      DefaultObject=Default__KismetSystemLibrary
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5092"
      PinName="WorldContextObject"
      PinToolTip="World Context Object\nObject リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/CoreUObject.Object')
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5093"
      PinName="Command"
      PinToolTip="Command\nString\n\nコンソールに送信するコマンド"
      PinType=(PinCategory="string")
      DefaultValue="SP.OutputDir g:/StereoCaptureFrames"
   End Object
   Begin Object Name="EdGraphPin_5094"
      PinName="SpecificPlayer"
      PinToolTip="Specific Player\nプレイヤーコントローラー リファレンス\n\n指定された場合、コンソールコマンドは特定のプレイヤーを経由して送信されます。"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.PlayerController')
   End Object
   FunctionReference=(MemberParent=Class'/Script/Engine.KismetSystemLibrary',MemberName="ExecuteConsoleCommand")
   Pins(0)=EdGraphPin'EdGraphPin_5089'
   Pins(1)=EdGraphPin'EdGraphPin_5090'
   Pins(2)=EdGraphPin'EdGraphPin_5091'
   Pins(3)=EdGraphPin'EdGraphPin_5092'
   Pins(4)=EdGraphPin'EdGraphPin_5093'
   Pins(5)=EdGraphPin'EdGraphPin_5094'
   NodePosX=3536
   NodePosY=1680
   NodeGuid=441A807E4D6B7FD26855BCA0248CA1F9
End Object
Begin Object Class=K2Node_CallFunction Name="K2Node_CallFunction_2506"
   Begin Object Class=EdGraphPin Name="EdGraphPin_5107"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5108"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5109"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5110"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5111"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5112"
   End Object
   Begin Object Name="EdGraphPin_5107"
      PinName="execute"
      PinToolTip="\n実行"
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2505.EdGraphPin_5090'
   End Object
   Begin Object Name="EdGraphPin_5108"
      PinName="then"
      PinToolTip="\n実行"
      Direction=EGPD_Output
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2525.EdGraphPin_5125'
   End Object
   Begin Object Name="EdGraphPin_5109"
      PinName="self"
      PinFriendlyName="ターゲット"
      PinToolTip="ターゲット\nKismet System Library リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.KismetSystemLibrary')
      DefaultObject=Default__KismetSystemLibrary
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5110"
      PinName="WorldContextObject"
      PinToolTip="World Context Object\nObject リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/CoreUObject.Object')
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5111"
      PinName="Command"
      PinToolTip="Command\nString\n\nコンソールに送信するコマンド"
      PinType=(PinCategory="string")
      DefaultValue="SP.HorizontalAngularIncrement 2"
   End Object
   Begin Object Name="EdGraphPin_5112"
      PinName="SpecificPlayer"
      PinToolTip="Specific Player\nプレイヤーコントローラー リファレンス\n\n指定された場合、コンソールコマンドは特定のプレイヤーを経由して送信されます。"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.PlayerController')
   End Object
   FunctionReference=(MemberParent=Class'/Script/Engine.KismetSystemLibrary',MemberName="ExecuteConsoleCommand")
   Pins(0)=EdGraphPin'EdGraphPin_5107'
   Pins(1)=EdGraphPin'EdGraphPin_5108'
   Pins(2)=EdGraphPin'EdGraphPin_5109'
   Pins(3)=EdGraphPin'EdGraphPin_5110'
   Pins(4)=EdGraphPin'EdGraphPin_5111'
   Pins(5)=EdGraphPin'EdGraphPin_5112'
   NodePosX=3552
   NodePosY=1856
   NodeGuid=9E02D93E4A94788A67B66DA852BCD521
End Object
Begin Object Class=K2Node_CallFunction Name="K2Node_CallFunction_2525"
   Begin Object Class=EdGraphPin Name="EdGraphPin_5125"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5126"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5127"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5128"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5129"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5130"
   End Object
   Begin Object Name="EdGraphPin_5125"
      PinName="execute"
      PinToolTip="\n実行"
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2506.EdGraphPin_5108'
   End Object
   Begin Object Name="EdGraphPin_5126"
      PinName="then"
      PinToolTip="\n実行"
      Direction=EGPD_Output
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2526.EdGraphPin_5143'
   End Object
   Begin Object Name="EdGraphPin_5127"
      PinName="self"
      PinFriendlyName="ターゲット"
      PinToolTip="ターゲット\nKismet System Library リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.KismetSystemLibrary')
      DefaultObject=Default__KismetSystemLibrary
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5128"
      PinName="WorldContextObject"
      PinToolTip="World Context Object\nObject リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/CoreUObject.Object')
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5129"
      PinName="Command"
      PinToolTip="Command\nString\n\nコンソールに送信するコマンド"
      PinType=(PinCategory="string")
      DefaultValue="SP.VerticalAngularIncrement 30"
   End Object
   Begin Object Name="EdGraphPin_5130"
      PinName="SpecificPlayer"
      PinToolTip="Specific Player\nプレイヤーコントローラー リファレンス\n\n指定された場合、コンソールコマンドは特定のプレイヤーを経由して送信されます。"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.PlayerController')
   End Object
   FunctionReference=(MemberParent=Class'/Script/Engine.KismetSystemLibrary',MemberName="ExecuteConsoleCommand")
   Pins(0)=EdGraphPin'EdGraphPin_5125'
   Pins(1)=EdGraphPin'EdGraphPin_5126'
   Pins(2)=EdGraphPin'EdGraphPin_5127'
   Pins(3)=EdGraphPin'EdGraphPin_5128'
   Pins(4)=EdGraphPin'EdGraphPin_5129'
   Pins(5)=EdGraphPin'EdGraphPin_5130'
   NodePosX=3552
   NodePosY=2032
   NodeGuid=C6B87C7242707337CCE7D2AB4212CD6B
End Object
Begin Object Class=K2Node_CallFunction Name="K2Node_CallFunction_2526"
   Begin Object Class=EdGraphPin Name="EdGraphPin_5143"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5144"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5145"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5146"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5147"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5148"
   End Object
   Begin Object Name="EdGraphPin_5143"
      PinName="execute"
      PinToolTip="\n実行"
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2525.EdGraphPin_5126'
   End Object
   Begin Object Name="EdGraphPin_5144"
      PinName="then"
      PinToolTip="\n実行"
      Direction=EGPD_Output
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2527.EdGraphPin_5161'
   End Object
   Begin Object Name="EdGraphPin_5145"
      PinName="self"
      PinFriendlyName="ターゲット"
      PinToolTip="ターゲット\nKismet System Library リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.KismetSystemLibrary')
      DefaultObject=Default__KismetSystemLibrary
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5146"
      PinName="WorldContextObject"
      PinToolTip="World Context Object\nObject リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/CoreUObject.Object')
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5147"
      PinName="Command"
      PinToolTip="Command\nString\n\nコンソールに送信するコマンド"
      PinType=(PinCategory="string")
      DefaultValue="SP.CaptureHorizontalFOV 30"
   End Object
   Begin Object Name="EdGraphPin_5148"
      PinName="SpecificPlayer"
      PinToolTip="Specific Player\nプレイヤーコントローラー リファレンス\n\n指定された場合、コンソールコマンドは特定のプレイヤーを経由して送信されます。"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.PlayerController')
   End Object
   FunctionReference=(MemberParent=Class'/Script/Engine.KismetSystemLibrary',MemberName="ExecuteConsoleCommand")
   Pins(0)=EdGraphPin'EdGraphPin_5143'
   Pins(1)=EdGraphPin'EdGraphPin_5144'
   Pins(2)=EdGraphPin'EdGraphPin_5145'
   Pins(3)=EdGraphPin'EdGraphPin_5146'
   Pins(4)=EdGraphPin'EdGraphPin_5147'
   Pins(5)=EdGraphPin'EdGraphPin_5148'
   NodePosX=3568
   NodePosY=2208
   NodeGuid=544847714E1C462704CBD894F18B7517
End Object
Begin Object Class=K2Node_CallFunction Name="K2Node_CallFunction_2527"
   Begin Object Class=EdGraphPin Name="EdGraphPin_5161"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5162"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5163"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5164"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5165"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5166"
   End Object
   Begin Object Name="EdGraphPin_5161"
      PinName="execute"
      PinToolTip="\n実行"
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2526.EdGraphPin_5144'
   End Object
   Begin Object Name="EdGraphPin_5162"
      PinName="then"
      PinToolTip="\n実行"
      Direction=EGPD_Output
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2529.EdGraphPin_5179'
   End Object
   Begin Object Name="EdGraphPin_5163"
      PinName="self"
      PinFriendlyName="ターゲット"
      PinToolTip="ターゲット\nKismet System Library リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.KismetSystemLibrary')
      DefaultObject=Default__KismetSystemLibrary
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5164"
      PinName="WorldContextObject"
      PinToolTip="World Context Object\nObject リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/CoreUObject.Object')
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5165"
      PinName="Command"
      PinToolTip="Command\nString\n\nコンソールに送信するコマンド"
      PinType=(PinCategory="string")
      DefaultValue="SP.ConcurrentCaptures 6"
   End Object
   Begin Object Name="EdGraphPin_5166"
      PinName="SpecificPlayer"
      PinToolTip="Specific Player\nプレイヤーコントローラー リファレンス\n\n指定された場合、コンソールコマンドは特定のプレイヤーを経由して送信されます。"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.PlayerController')
   End Object
   FunctionReference=(MemberParent=Class'/Script/Engine.KismetSystemLibrary',MemberName="ExecuteConsoleCommand")
   Pins(0)=EdGraphPin'EdGraphPin_5161'
   Pins(1)=EdGraphPin'EdGraphPin_5162'
   Pins(2)=EdGraphPin'EdGraphPin_5163'
   Pins(3)=EdGraphPin'EdGraphPin_5164'
   Pins(4)=EdGraphPin'EdGraphPin_5165'
   Pins(5)=EdGraphPin'EdGraphPin_5166'
   NodePosX=3552
   NodePosY=2368
   NodeGuid=3B0A875844490E2E566B208034B58A79
End Object
Begin Object Class=K2Node_CallFunction Name="K2Node_CallFunction_2529"
   Begin Object Class=EdGraphPin Name="EdGraphPin_5179"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5180"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5181"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5182"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5183"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5184"
   End Object
   Begin Object Name="EdGraphPin_5179"
      PinName="execute"
      PinToolTip="\n実行"
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2527.EdGraphPin_5162'
   End Object
   Begin Object Name="EdGraphPin_5180"
      PinName="then"
      PinToolTip="\n実行"
      Direction=EGPD_Output
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2530.EdGraphPin_5197'
   End Object
   Begin Object Name="EdGraphPin_5181"
      PinName="self"
      PinFriendlyName="ターゲット"
      PinToolTip="ターゲット\nKismet System Library リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.KismetSystemLibrary')
      DefaultObject=Default__KismetSystemLibrary
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5182"
      PinName="WorldContextObject"
      PinToolTip="World Context Object\nObject リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/CoreUObject.Object')
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5183"
      PinName="Command"
      PinToolTip="Command\nString\n\nコンソールに送信するコマンド"
      PinType=(PinCategory="string")
      DefaultValue="SP.CaptureSlicePixelWidth 720"
   End Object
   Begin Object Name="EdGraphPin_5184"
      PinName="SpecificPlayer"
      PinToolTip="Specific Player\nプレイヤーコントローラー リファレンス\n\n指定された場合、コンソールコマンドは特定のプレイヤーを経由して送信されます。"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.PlayerController')
   End Object
   FunctionReference=(MemberParent=Class'/Script/Engine.KismetSystemLibrary',MemberName="ExecuteConsoleCommand")
   Pins(0)=EdGraphPin'EdGraphPin_5179'
   Pins(1)=EdGraphPin'EdGraphPin_5180'
   Pins(2)=EdGraphPin'EdGraphPin_5181'
   Pins(3)=EdGraphPin'EdGraphPin_5182'
   Pins(4)=EdGraphPin'EdGraphPin_5183'
   Pins(5)=EdGraphPin'EdGraphPin_5184'
   NodePosX=3568
   NodePosY=2528
   NodeGuid=C24A900B418C091DA072F0978FD01CFC
End Object
Begin Object Class=K2Node_CallFunction Name="K2Node_CallFunction_2530"
   Begin Object Class=EdGraphPin Name="EdGraphPin_5197"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5198"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5199"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5200"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5201"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5202"
   End Object
   Begin Object Name="EdGraphPin_5197"
      PinName="execute"
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2529.EdGraphPin_5180'
   End Object
   Begin Object Name="EdGraphPin_5198"
      PinName="then"
      Direction=EGPD_Output
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2528.EdGraphPin_5215'
   End Object
   Begin Object Name="EdGraphPin_5199"
      PinName="self"
      PinFriendlyName="ターゲット"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.KismetSystemLibrary')
      DefaultObject=Default__KismetSystemLibrary
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5200"
      PinName="WorldContextObject"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/CoreUObject.Object')
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5201"
      PinName="Command"
      PinType=(PinCategory="string")
      DefaultValue="SP.ShouldOverrideInitialYaw 0"
   End Object
   Begin Object Name="EdGraphPin_5202"
      PinName="SpecificPlayer"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.PlayerController')
   End Object
   FunctionReference=(MemberParent=Class'/Script/Engine.KismetSystemLibrary',MemberName="ExecuteConsoleCommand")
   Pins(0)=EdGraphPin'EdGraphPin_5197'
   Pins(1)=EdGraphPin'EdGraphPin_5198'
   Pins(2)=EdGraphPin'EdGraphPin_5199'
   Pins(3)=EdGraphPin'EdGraphPin_5200'
   Pins(4)=EdGraphPin'EdGraphPin_5201'
   Pins(5)=EdGraphPin'EdGraphPin_5202'
   NodePosX=3568
   NodePosY=2704
   NodeGuid=5FC24F054B88E904591E618EBECF5C80
End Object
Begin Object Class=K2Node_CallFunction Name="K2Node_CallFunction_2528"
   Begin Object Class=EdGraphPin Name="EdGraphPin_5215"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5216"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5217"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5218"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5219"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_5220"
   End Object
   Begin Object Name="EdGraphPin_5215"
      PinName="execute"
      PinToolTip="\n実行"
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2530.EdGraphPin_5198'
   End Object
   Begin Object Name="EdGraphPin_5216"
      PinName="then"
      PinToolTip="\n実行"
      Direction=EGPD_Output
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2504.EdGraphPin_29560'
   End Object
   Begin Object Name="EdGraphPin_5217"
      PinName="self"
      PinFriendlyName="ターゲット"
      PinToolTip="ターゲット\nKismet System Library リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.KismetSystemLibrary')
      DefaultObject=Default__KismetSystemLibrary
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5218"
      PinName="WorldContextObject"
      PinToolTip="World Context Object\nObject リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/CoreUObject.Object')
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_5219"
      PinName="Command"
      PinToolTip="Command\nString\n\nコンソールに送信するコマンド"
      PinType=(PinCategory="string")
      DefaultValue="SP.StepCaptureWidth 4096"
   End Object
   Begin Object Name="EdGraphPin_5220"
      PinName="SpecificPlayer"
      PinToolTip="Specific Player\nプレイヤーコントローラー リファレンス\n\n指定された場合、コンソールコマンドは特定のプレイヤーを経由して送信されます。"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.PlayerController')
   End Object
   FunctionReference=(MemberParent=Class'/Script/Engine.KismetSystemLibrary',MemberName="ExecuteConsoleCommand")
   Pins(0)=EdGraphPin'EdGraphPin_5215'
   Pins(1)=EdGraphPin'EdGraphPin_5216'
   Pins(2)=EdGraphPin'EdGraphPin_5217'
   Pins(3)=EdGraphPin'EdGraphPin_5218'
   Pins(4)=EdGraphPin'EdGraphPin_5219'
   Pins(5)=EdGraphPin'EdGraphPin_5220'
   NodePosX=3568
   NodePosY=2880
   NodeGuid=7BD4A1A64B609D1C96829BB97AA0C8BB
End Object
Begin Object Class=K2Node_CallFunction Name="K2Node_CallFunction_2504"
   Begin Object Class=EdGraphPin Name="EdGraphPin_29560"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_29561"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_29562"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_29563"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_29564"
   End Object
   Begin Object Class=EdGraphPin Name="EdGraphPin_29565"
   End Object
   Begin Object Name="EdGraphPin_29560"
      PinName="execute"
      PinToolTip="\n実行"
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_CallFunction_2528.EdGraphPin_5216'
   End Object
   Begin Object Name="EdGraphPin_29561"
      PinName="then"
      PinToolTip="\n実行"
      Direction=EGPD_Output
      PinType=(PinCategory="exec")
      LinkedTo(0)=EdGraphPin'K2Node_ExecutionSequence_6.EdGraphPin_3705'
   End Object
   Begin Object Name="EdGraphPin_29562"
      PinName="self"
      PinFriendlyName="ターゲット"
      PinToolTip="ターゲット\nKismet System Library リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.KismetSystemLibrary')
      DefaultObject=Default__KismetSystemLibrary
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_29563"
      PinName="WorldContextObject"
      PinToolTip="World Context Object\nObject リファレンス"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/CoreUObject.Object')
      bHidden=True
   End Object
   Begin Object Name="EdGraphPin_29564"
      PinName="Command"
      PinToolTip="Command\nString\n\nコンソールに送信するコマンド"
      PinType=(PinCategory="string")
      DefaultValue="SP.PanoramicMovie 0 4200"
   End Object
   Begin Object Name="EdGraphPin_29565"
      PinName="SpecificPlayer"
      PinToolTip="Specific Player\nプレイヤーコントローラー リファレンス\n\n指定された場合、コンソールコマンドは特定のプレイヤーを経由して送信されます。"
      PinType=(PinCategory="object",PinSubCategoryObject=Class'/Script/Engine.PlayerController')
   End Object
   FunctionReference=(MemberParent=Class'/Script/Engine.KismetSystemLibrary',MemberName="ExecuteConsoleCommand")
   Pins(0)=EdGraphPin'EdGraphPin_29560'
   Pins(1)=EdGraphPin'EdGraphPin_29561'
   Pins(2)=EdGraphPin'EdGraphPin_29562'
   Pins(3)=EdGraphPin'EdGraphPin_29563'
   Pins(4)=EdGraphPin'EdGraphPin_29564'
   Pins(5)=EdGraphPin'EdGraphPin_29565'
   NodePosX=3552
   NodePosY=3072
   NodeGuid=8CF73B5D47BCA45C92A0EE9FAB2F4080
End Object
```


重要な個所は
最初の
__SP.OutputDir 保存フォルダ__
と
最後の
__SP.PanoramicMovie 開始フレーム　終了フレーム__
の部分です

#【エディタの固定フレームレート起動】

ue4のエディタを固定フレームレートで起動するためにエディタの起動パラメータを設定します。

-usefixedtimestep -fps=60 -notexturestreaming
↑これをue4エディタの起動パラメータに設定します。

エディタの実行ファイルのシュートカットを作るのが比較的簡単かと思います。
![8.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/9a2959f8-07ee-1b26-9df1-b9191db68fcf.jpeg)

起動パラメータを設定します。

![9.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/df4d819c-d02c-eebb-de7a-30a78768bb27.jpeg)

#【映像のステレオ化】

先ほどのコンソールコマンドのBluePrintをBegingPlayにつないで
そのあとにマチネの映像やゲームなどを動作させれば、指定したフレーム数自動的にキャプチャを行います。
![10.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/a357dd4f-9dc7-7913-b9f7-a11e558a6e07.jpeg)

__SP.OutputDir 保存フォルダ__のフォルダに少し時間がかかりますが
連番画像が作成されていきます。

参考までに私の環境では100フレームの出力するのに5時間かかりました、、、

大きい動画をキャプチャする場合は環境にもよりますが数日～数週間必要かもしれません、、、

#【連番ファイルの動画化】

特にここは説明しませんが
![Frame_00000.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/208cd768-c2f8-2b9e-2c8b-68b7cc3ba1a1.jpeg)

こんな感じで作成される連番画像ファイルを何らかのツールで動画化する必要があります。

![11.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/ea0898b3-0123-cf72-3de7-c3b76e2033b5.jpeg)

無料ものならaviutl などでも可能だったと思いますが。
出力されるファイルがjpgなのでどうだったか。。。
私が知る限りaviutlはbmpの連番ファイルだった気がするので、、、

__ここで注意が必要です。__
映像の解像度が4096×4096ではHD映像にならないので

1920x1080または3840x2160の16:9のSpherical（Equirectangular）な左目用・右目用映像を用意しなければなりません。
左右の左右が一つになる画像ですので横のサイズを２倍して

__アップロードするmp4のサイズは1920x2160または3840x4320になります。__

私の場合はAfter Effectで映像サイズを変更し結合して動画化し、MediaEncoderでMP4化しました。

例として私の設定したコンポジションは以下です。
![14.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/bf8630b0-1592-dacc-b965-8783b7c52f8f.jpeg)


#【メタデータの挿入】
MP4の動画化が終わったらyoutubeが360度動画として認識できるように情報を追加しなければなりません。

https://support.google.com/youtube/answer/6316263?hl=ja&ref_topic=2888648
↑ここのサイトからツールをダウンロードします。

赤枠のツールをダウンロードします。
![12.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/21d0f767-a8f8-cd18-2ee5-b2c833ec2215.jpeg)

ツールをダウンロードしたら
ツールを起動し

![15.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/05d42e43-c9e3-2c67-9dc9-5432908fd515.jpeg)

openで先ほど作成した結合動画を開きます。

開いたら赤字のチェックボックスをチェックします。
音声のない動画ですと下のチェックボックスはチェックできません。
![16.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/3dcf5b19-6e64-5aa9-ca06-b4dbc092f32b.jpeg)

下記のボタンを押してメタデータの入ったMP4を出力する場所を指定します。
![17.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/f56933ff-4292-ddef-e7d8-036e19fd6cbd.jpeg)


#【youtubeにアップロード】

メタデータの挿入が終わったらyoutubeにアップロードします。

赤枠のようになれば成功です。
![18.jpg](https://qiita-image-store.s3.amazonaws.com/0/59114/056e6b87-6240-eef0-f804-75ede51b39f4.jpeg)


#【最後に】

この動画作成はレンダリングに相当時間がかかるのでレンダリング前の
事前チェックを万全にしたいですね。
（数日経って間違いに気づくときついので）

最後まで読んでいただいてありがとうございます。