##今回やること
- UnityのuGUI(UI)の機能を使って、フェードイン・フェードアウトの演出を作る。
- そのためにシェーダーを自作する。
トランジションって調べるとよく出てくるuGUIとは? → UnityのUI機能のこと(Canvasなど)。
この機能を応用することで、トランジション(シーン遷移のときの画面演出)が実装できる1。
全体として以下2の記事を参考にした。
##1. ルール画像の作成
Unityでは、画像素材に対して設定を行うことで黒部分の透明化を行うことができる。α値を操作すれば、グラデーションのように画面が動いて切り替わる効果のトランジション(画面遷移)を作成できる。
今回は以下のような画像(透過なしPNGファイル)をPhotoshopで作成し、Rule01として使用した。
以下の画像(Rule01.png)は自作のため使用自由とする。
##2. Spriteとしての調整
Assetに入れた状態から、素材をダブルクリックしてInspectorを開く。設定は以下の通り行った。
-
Texture Type
をSprite(2D and UI)
-
sRGB
のチェックボックスをオフ -
Alpha Source
をFrom Gray Scale
に設定
##3. Imageの設定
-
Hierarchy
からCreate > UI > Image
を選んでオブジェクトを作る - ポジションを(0,0,0)に変更(カメラの中心位置に置かれる)
- Source Imageの中にSprite設定を行った画像をいれる
- Preserve Aspectにチェックを入れ(縦横比を固定できる)、画面におさまるサイズにWidthを変更
参考:Unity Imageに表示する方法: https://www.sejuku.net/blog/56133
##4. シェーダーの作成
参考: 【Unity入門】Shaderってなんだ?誰でもわかるシェーダー解説!, 2018, https://www.sejuku.net/blog/66319
シェーダーとは? → テクスチャをどのように表示するかをきめるプログラム
Unityでは、シェーダーはHLSL言語で記述され、UnityのScriptの書き方(C#)とは異なる言語である3。
表示させたルール画像をつかってテクスチャの表示方法を決めたいので、シェーダーのプログラム(スクリプト)を書いてImageに反映させます。
###4.1 マテリアルの作成
シェーダースクリプトをアタッチするためにはマテリアルが必要なので、トランジション用マテリアルを作成してからImageにアタッチする。
###4.2 シェーダースクリプトを作成する
Create
>Shader
>UnlitShader
でShaderを作成する。※名前注意!
####▼注意! shaderの名前を後から変更すると…(間違い探し)
右側に注目。名前がUnlit/NewUnlitShader
になってしまうので、アタッチしようとするときに名前がわかりづらい。作成直後に名前が変更できるときがあるので、ここで変更しておくとよい。
なお、Shaderのスクリプトを変更する際にスクリプト内で名前を変更すれば、こちらのInspector表示上の名前も変わる。名前の不一致に注意。
###4.3 シェーダースクリプトをアタッチする
マテリアルをInspector画面に表示する。Shader
>Unlit
>"Shaderの名前"
からアタッチできる。
▼アタッチしたところ。シェーダースクリプトの中身がまだ空なのでただの画像が表示されている。
###4.4 シェーダースクリプトの中身(HLSL)の作成
エディタでShaderを表示し、コードを変更して保存する。
UnityのScriptを作ったときと同様に、あらかじめ書き込まれている文章があるが、特にこだわりがなければ以下のコードのコピペで構わない。
スクリプトはUnityでトランジション演出を実装する の記事から、**時間によって画像のα値を増減する
**の項目より引用。※Unityのスクリプト同様、名前に注意すること!
Shader "Unlit/Shaderの名前" //ここの名前を変えるのを忘れずに!
{
Properties
{
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
_Color("Tint", Color) = (1,1,1,1)
_Alpha ("Time", Range(0, 1)) = 0
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Cull Off
Lighting Off
ZWrite Off
ZTest[unity_GUIZTestMode]
Fog{ Mode Off }
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
fixed _Alpha;
sampler2D _MainTex;
// 頂点シェーダーの基本
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw - 1.0) * float2(-1,1);
#endif
return OUT;
}
// 通常のフラグメントシェーダー
fixed4 frag(v2f IN) : SV_Target
{
half alpha = tex2D(_MainTex, IN.texcoord).a;
alpha = saturate(alpha + (_Alpha * 2 - 1));
return fixed4(_Color.r, _Color.g, _Color.b, alpha);
}
ENDCG
}
}
FallBack "UI/Default"
}
##5. Shaderを動かすスクリプト(C#)の作成
C#スクリプトを作成。
スクリプトはUnityでトランジション演出を実装する の記事から、**時間を制御するスクリプト
**の項目より引用。
####▼暗転用C#スクリプト
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class Transition : MonoBehaviour
{
[SerializeField]
private Material _transitionIn;
void Start()
{
StartCoroutine( BeginTransition() );
}
IEnumerator BeginTransition()
{
yield return Animate( _transitionIn, 1 );
}
/// <summary>
/// time秒かけてトランジションを行う
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
IEnumerator Animate(Material material, float time)
{
GetComponent<Image>().material = material;
float current = 0;
while (current < time) {
material.SetFloat( "_Alpha", current / time );
yield return new WaitForEndOfFrame();
current += Time.deltaTime;
}
material.SetFloat( "_Alpha", 1 );
}
}
コピペそのままでは**エラー**が出るので、まずオブジェクト(Image)にアタッチしてから、NoneになっているTransition In
変数に、マテリアルをアタッチする。
▼スクリプトを入力し、Transition In
にマテリアルをアタッチしたところ。
動かしてみると→
マテリアルの色で暗転するようになりました。
####▼明転用C#スクリプト(暗転用と同様に設定)
スクリプトはUnityでトランジション演出を実装する の記事から、**時間を制御するスクリプト
**の項目を一部改変。
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class Transition02 : MonoBehaviour
{
[SerializeField]
private Material _transitionIn;
void Start()
{
StartCoroutine( BeginTransition() );
}
IEnumerator BeginTransition()
{
yield return Animate( _transitionIn, 1 );
}
/// <summary>
/// time秒かけてトランジションを行う
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
IEnumerator Animate(Material material, float time)
{
GetComponent<Image>().material = material;
float current = 0;
while (current < time) {
material.SetFloat( "_Alpha", 1 - current / time );
yield return new WaitForEndOfFrame();
current += Time.deltaTime;
}
material.SetFloat( "_Alpha", 0 );
}
}
##6. 完成・アレンジ
####★マテリアルの色(Tint)
を変更すると、明転・暗転の色が変わる。
####★ルール画像を変更4すれば、いろいろな模様で暗転・明転させることができる。
##補記
途中でトランジションのスペル(綴り)がTransitionであることを知りました。やっちまった…
-
uGUI (UnityのUI機能) の使い方まとめ, 2016, http://mikan-daisuki.hatenablog.com/entry/2016/01/11/175010 ↩
-
Unityでトランジション演出を実装する,2019, https://blog.cfm-art.net/archives/963 ↩
-
Unityリファレンス(Unityで使用するシェーダー言語), https://docs.unity3d.com/ja/2018.4/Manual/SL-ShadingLanguage.html ↩
-
このルール画像を使っています(自作のため使用自由)
####★このスクリプトのままではStart時にCoroutineが始まってしまうので、Coroutineの開始を適宜調整する。 ↩