強火で進め

このブログではプログラム関連の記事を中心に書いてます。こちらで( http://blog.livedoor.jp/tsuyobi-outdoor/ ) アウトドア関連の記事も書いてます。

VideoPlayer の renderMode と aspectRatio の設定による違いの解説

今回の記事のサンプルはこちらにアップして有ります。

nakamura001/Unity-VideoPlayerSample2: Unity の VideoPlayer のサンプル
https://github.com/nakamura001/Unity-VideoPlayerSample2

renderMode の設定

renderMode に設定可能な値は以下。

説明
CameraFarPlane カメラの一番奥(Far Plane)の位置にレンダリング
CameraNearPlane カメラの最前面(Near Plane)の位置にレンダリング
RenderTexture Render Texture にレンダリング
MaterialOverride 現在設定されている Material を上書きしてレンダリング
APIOnly 直接画面にはレンダリングせず、プログラム内で Texture プロパティを使いたい時に使用

コード

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
using UnityEngine.SceneManagement;

public class Test : MonoBehaviour {
	public VideoPlayer videoPlayer;
	public Slider alphaSlider;
	public RenderTexture renderTexture;
	public Renderer rendrer;
	public RawImage rawImage;
	int refreshCount = 0;

	void SetSendFrameReadyEvents(bool enable) {
		// 参考:http://stackoverflow.com/questions/42747285/getting-current-frame-from-videoplayer/42747609#42747609
		if (enable) {
			videoPlayer.sendFrameReadyEvents = true;
			videoPlayer.frameReady += OnNewFrame;
		} else {
			if (videoPlayer.sendFrameReadyEvents) {
				videoPlayer.frameReady -= OnNewFrame;
			}
			videoPlayer.sendFrameReadyEvents = false;
		}
	}

	void OnNewFrame(VideoPlayer source, long frameIdx)
	{
		refreshCount++;
		// 10フレームに1回更新する
		if (refreshCount >= 10) {
			rawImage.texture = source.texture;
			refreshCount = 0;
		}
	}

	void UpdateAlpha() {
		UpdateAlpha (alphaSlider.value);
	}

	void UpdateAlpha(float alpha) {
		videoPlayer.targetCameraAlpha = alpha;
	}

	public void PlayVideo(string mode) {
		UpdateAlpha ();
		switch (mode) {
		case "CameraFarPlane":
			SetSendFrameReadyEvents (false);
			videoPlayer.renderMode = VideoRenderMode.CameraFarPlane;
			break;
		case "CameraNearPlane":
			SetSendFrameReadyEvents (false);
			videoPlayer.renderMode = VideoRenderMode.CameraNearPlane;
			break;
		case "RenderTexture":
			SetSendFrameReadyEvents (false);
			// RenderTexture の場合には targetTexture を設定しておく必要有り
			videoPlayer.targetTexture = renderTexture;
			videoPlayer.renderMode = VideoRenderMode.RenderTexture;
			break;
		case "MaterialOverride":
			SetSendFrameReadyEvents (false);
			// MaterialOverride の場合には targetMaterialRenderer を設定しておく必要有り
			videoPlayer.targetMaterialRenderer = rendrer;
			videoPlayer.renderMode = VideoRenderMode.MaterialOverride;
			break;
		case "APIOnly":
			// renderMode が APIOnly の時にはフレームが準備されるのを待つ
			SetSendFrameReadyEvents (true);
			videoPlayer.renderMode = VideoRenderMode.APIOnly;
			break;
		}
		videoPlayer.Play ();
	}

	public void Reset() {
		SceneManager.LoadScene (SceneManager.GetActiveScene ().buildIndex);
	}
}

動画

それぞれに切り替えた時の動作を撮影しました。
※サンプルプロジェクトの Sample1 というシーンを開くと動作確認できます。

MaterialOverride と APIOnly の場合にはアルファ値の設定は反映されない様です。
RenderTexture は特定のアルファ値をさかいに表示非表示が切り替わっていますがこれは RenderTexture を使用している Material の Rendering Mode が Cutout にしている為です。じんわりと透過させたい場合には Fade を選択して下さい。

Unity - Scripting API: Video.VideoPlayer.renderMode
https://docs.unity3d.com/560/Documentation/ScriptReference/Video.VideoPlayer-renderMode.html

Unity - Scripting API: VideoRenderMode
https://docs.unity3d.com/560/Documentation/ScriptReference/Video.VideoRenderMode.html

aspectRatio の設定

説明
NoScaling ターゲットエリアの中央に動画のサイズのままでレンダリング。ターゲットエリアの方が大きい場合には余白が生まれ、小さい為にはみ出る場合にはその部分はレンダリングされない
FitVertically ターゲットエリアの縦方向にピッタリのサイズになる様にスケーリング。サイズにより、横方向には余白が出たり、はみ出たりする事が有る
FitHorizontally ターゲットエリアの横方向にピッタリのサイズになる様にスケーリング。サイズにより、縦方向には余白が出たり、はみ出たりする事が有る
FitInside ターゲットエリアの内側にアスペクト比を保ったままで全体が収まる様にスケーリング。サイズにより、縦または横方向に余白が出る事が有る
FitOutside ターゲットエリアに余白が出ない様にスケーリング。サイズにより、縦または横がターゲットエリアをはみ出る(はみ出た部分はレンダリングされない)
Stretch ターゲットエリアの内側に全体が収まる様にスケーリング

ほとんどの場合には FitInside を選択で問題無いかと思います。

Unity - Scripting API: VideoAspectRatio
https://docs.unity3d.com/560/Documentation/ScriptReference/Video.VideoAspectRatio.html

Unity - Scripting API: Video.VideoPlayer.aspectRatio
https://docs.unity3d.com/560/Documentation/ScriptReference/Video.VideoPlayer-aspectRatio.html

動画

輪郭部分に青いラインを引いた横長と縦長の動画を準備し、それを再生した時のそれぞれの動きを撮影しました。
※サンプルプロジェクトの Sample2 というシーンを開くと動作確認できます。