タイマーストップの時間に応じて、表示される動画を変える。
ゲーム内で動画を使う場面は、オープニングやエンディングのカットシーン、チュートリアルの説明、プレイヤーの進捗や成績を示すグラフィックスなど
多岐に渡って利用します。
また、アニメ―ションやエフェクトを作成するとUnity内やBlenderで作る必要があるので、
プログラミング以外にもタスクが増えて作品完成までの道のりが遠くなってしまいます。
しかし、これらの効果を動画で補うことで簡単に追加することができます。
本記事はUnityの標準Video Playerの使い方について解説します。
- Unityで動画を再生したい。
- Video Playerの使い方を知りたい。
- アニメ―ションやエフェクトを追加したい。
Video Player
Unityで動画を再生するためのcomponent「Video Player」があります。
「VideoPlayerコンポーネント」と「VideoPlayerスクリプト」を使うことで高度な動画の制御が可能になります。
Raw Image
ゲームオブジェクトを用意する必要があります。
空オブジェクトでもよいですが、動画の比率調整がしやすい「RawImage」をおすすめします。
Hierarchyウィンドウのプラスから「UI>Raw Image」を選択します。
Inspectorウィンドウの「Rect Transform」でPos(xyz)を0にして、
Width(幅)、Height(高さ)を動画のサイズと合わせてください。
動画がゲーム枠に収まらない場合は、Gameビューの項目からサイズ変更をしてください。
「RawImage」のInspectorウィンドウ下部にcomponentの項目があるので、
「Video Player」を追加してください。
「Video Clip」に動画をアタッチしてゲームを再生しても動画が再生されません。
原因は、RawImageに「Texture」が存在しないからです。
Render Texture
次にprojectウィンドウのプラスから「Render Texture」を追加して、
RawImageにアタッチすると、動画をgameビューに表示できます。
動画の比率はTextureのsizeに依存するので、動画の幅(Raw Image)と同じにしてください。
以上までの工程を進めて、動画を表示することができます。
動画のクロマキー
動画をアニメーションや演出、エフェクトとして使いたい場合は、
映像から背景の色を分離(クロマキー)する必要があります。
Unityは、Shaderを使うことでクロマキーが可能です。
projectウィンドウから「Shader>Standard Surface Shader」と「Material」を追加してください。
Shaderをクリックして、デフォルトから次のコードに編集してください。
Shader "Custom/ChromaKeyShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_ChromaKeyColor ("Chroma Key Color", Color) = (1,1,1,1)
_Threshold ("Threshold", Range(0, 1)) = 0.1
}
SubShader
{
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _ChromaKeyColor;
float _Threshold;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
if (distance(col.rgb, _ChromaKeyColor.rgb) < _Threshold)
{
discard;
}
return col;
}
ENDCG
}
}
}
MaterialのInspectorウィンドウからShaderを紐づけます。
Shaderの項目のPassは、上記のコードの先頭になります。
要するに、「”Custom/ChromaKeyShader”」を選択して下さい。
スポイトでクロマキー色を抽出して、Sliderを動かします。
背景色は少し残っていますが、数字が大きすぎると抽出が強くなってしまいます。
完全なクロマキーには限界があり、境界部分はくっきりと色分けする必要があります。
白と黄緑は明度が近いので、緑を濃くするとよりきれいにできるかと思います。
ビデオをスクリプトで制御
動画をスクリプトで制御していきます。
プログラム例として、体内時計ゲームを作成します。
- Step1Startボタンで時間を進める。
- Step2StartからStopに切り替わったボタンで時間が止まる。
- Step34.5秒~5秒以内で停止すると成功動画。それ以外は失敗動画。
- Step42.5秒以降は、表示される文字は非表示。
ソースコード
using UnityEngine;
using TMPro;
using UnityEngine.Video;
public class VideoController : MonoBehaviour
{
public GameObject[] sets; // 正解不正解の表示-オブジェクト
private VideoPlayer[] videoPlayers; // 正解不正解の表示-ビデオ
public TextMeshProUGUI timeText;
public TextMeshProUGUI buttonText;
private float timer = 0f; // 制限時間
private bool isTimeUp = true; //タイマーストップ
void Start()
{
// ビデオを保存しているオブジェクトをビデオにする
videoPlayers = new VideoPlayer[sets.Length];
for (int i = 0; i < sets.Length; i++)
{
videoPlayers[i] = sets[i].GetComponentInChildren<VideoPlayer>();
videoPlayers[i].loopPointReached += OnVideoEnd; // ループしない
}
Next();
}
void Update()
{
if (!isTimeUp)
{
timer += Time.deltaTime; // タイマーを更新
timeText.text = timer.ToString("F1"); // 残り時間を表示
if (timer > 2.5)
{
timeText.gameObject.SetActive(false);
}
if (timer > 5)
{
timeText.gameObject.SetActive(true);
isTimeUp = true;
sets[1].SetActive(true); // 不正解を表示
videoPlayers[1].Play(); // 動画を再生
}
}
}
public void ToggleTimer()
{
isTimeUp = !isTimeUp; // タイマーの状態を切り替える
buttonText.text = isTimeUp ? "Start" : "Stop"; // ボタンのテキストを更新
timeText.gameObject.SetActive(true);
if (isTimeUp)
{
if (timer >= 4.5f && timer <= 5f)
{
sets[0].SetActive(true); // 正解を表示
videoPlayers[0].Play(); // 動画を再生
}
else
{
sets[1].SetActive(true); // 不正解を表示
videoPlayers[1].Play(); // 動画を再生
}
}
}
void OnVideoEnd(VideoPlayer vp)
{
Next();
}
public void Next()
{
buttonText.text = "Start";
isTimeUp = true; // タイマーを停止
timer = 0f; // タイマーをリセット
timeText.text = timer.ToString("F1"); // 残り時間を表示
// 動画非表示
foreach (GameObject set in sets)
{
set.SetActive(false);
}
}
}
UdemyでUnityを学習
Udemyは、オンデマンド式の学習講座です。
趣味から実務まで使えるおすすめの講座を紹介します。
ビックセール開催中(12月19日まで)
対象のコースが1500円から(最大95%OFF)
- 【Unity C# ゲーム開発超入門】7つのミニゲームを作っておぼえる!UnityとC#講座
Unityで頻出の機能を実際のゲーム作りで学習。
何か作りたい、今後の開発で役立てたい初心者におすすめ
- 【Unity C# ゲーム開発初心者レベルアップ】7つのトランプゲームを作っておぼえる!UnityとC#講座
トランプやボードゲーム作りに特化している講座。
テーブルゲームを作りたい人におすすめ。
- 【全行程を網羅!最初に学びたい総合学習】Unityワールド制作講座
Unityワールド制作の全工程を学習できる講座。
RPGを作りたい人におすすめ。
- Unity ゲーム開発:インディーゲームクリエイターが教える C#の基礎からゲームリリースまで【スタジオしまづ】
C#の文法やApp StoreとGoogle Playへゲームをリリース方法を解説。
ゲームを出品したい人におすすめ。
解説
- 名前空間
「using UnityEngine」:Unityのクラスや機能を使用するために必要です。
「using TMPro」:TextMesh Proを使用するために必要です。
「using UnityEngine.Video」:ビデオをスクリプトで扱うために必要です。
- フィールド(メンバ変数)
「sets」: 正解と不正解の表示に使用されるゲームオブジェクトの配列です。
「videoPlayers」: ゲームオブジェクト内の VideoPlayer コンポーネントを格納する VideoPlayer 配列です。
「timeText」: 制限時間を表示するための TextMeshProUGUI コンポーネントです。
「buttonText」: ボタンのテキストを更新するための TextMeshProUGUI コンポーネントです。
「timer」: 制限時間を保持するための変数です。
「isTimeUp」: タイマーが停止しているかどうかを示すブール値です。
- Startメソッド
ゲームオブジェクト内の VideoPlayer コンポーネントを取得し、
ループポイントが到達したときに OnVideoEnd メソッドを呼び出すイベントハンドラーを設定します。
Next メソッドを呼び出して最初の設定を行います。
- Updateメソッド
タイマーが停止していない場合、タイマーを更新し、画面に小数第1位まで表示します。
2.5秒以降は文字を非表示、5秒超えると失敗になります。
- ToggleTimerメソッド
UIボタンを押すことで処理されます。
タイマーの状態を切り替え、ボタンのテキストを更新します。
タイマーが再開された場合、制限時間が一定の範囲内にあるかどうかを確認し、
それに応じて正解または不正解のビデオを再生します。
- OnVideoEnd メソッド
ビデオ再生が終了したときに呼び出され、Next メソッドを呼び出して次の設定を行います。
- Next メソッド
制限時間やタイマーをリセットし、ビデオを非表示にします。
実演
各々の変数にゲームオブジェクトをアタッチします。
規定の時間内でボタンを押すと、成功に相当する動画が再生されます。
対して、時間外にボタンを押す。
5秒超過してしまった場合は失敗に相当する動画が再生されます。
動画再生が終わるとNextメソッドが発動して、
動画は非表示になり、時間は0秒に戻ります。
動画を再生するときに、別の動画が一瞬映ることがあります。
しかし、Hierarchyウィンドウのオブジェクトに注目すると、無効の状態です。
テクスチャーに動画を写すときに、
前の動画最後の1フレームと動画最初が残っていることが原因だと考えられます。
対処法は表示したいものを消して、透過する背景を少し動画に残しておけばよいでしょう。
まとめ
Unityで動画を再生するには、componentからVideo Playerを使います。
また、クロマキーで背景を透過させることでアニメ―ションとして利用できます。