LoginSignup
5
3

More than 3 years have passed since last update.

[Unity初心者向け]画像を使ってシーン移動の演出をつくろう(トランジション)

Last updated at Posted at 2021-02-27

今回やること

  • UnityのuGUI(UI)の機能を使って、フェードイン・フェードアウトの演出を作る。
  • そのためにシェーダーを自作する。

トランジションって調べるとよく出てくるuGUIとは? → UnityのUI機能のこと(Canvasなど)。
この機能を応用することで、トランジション(シーン遷移のときの画面演出)が実装できる1
全体として以下2の記事を参考にした。

1. ルール画像の作成

Unityでは、画像素材に対して設定を行うことで黒部分の透明化を行うことができる。α値を操作すれば、グラデーションのように画面が動いて切り替わる効果のトランジション(画面遷移)を作成できる。
今回は以下のような画像(透過なしPNGファイル)をPhotoshopで作成し、Rule01として使用した。

以下の画像(Rule01.png)は自作のため使用自由とする。
Rule01.png

2. Spriteとしての調整

Assetに入れた状態から、素材をダブルクリックしてInspectorを開く。設定は以下の通り行った。
- Texture TypeSprite(2D and UI)
- sRGBのチェックボックスをオフ
- Alpha SourceFrom Gray Scaleに設定

スクリーンショット 2021-02-20 19.09.21.png

3. Imageの設定

  • HierarchyからCreate > UI > Imageを選んでオブジェクトを作る
  • ポジションを(0,0,0)に変更(カメラの中心位置に置かれる)
  • Source Imageの中にSprite設定を行った画像をいれる
  • Preserve Aspectにチェックを入れ(縦横比を固定できる)、画面におさまるサイズにWidthを変更

スクリーンショット 2021-02-20 19.07.24.png

参考: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にアタッチする。
スクリーンショット 2021-02-20 20.17.45.png

4.2 シェーダースクリプトを作成する

Create>Shader>UnlitShaderでShaderを作成する。※名前注意!
スクリーンショット 2021-02-20 20.37.29.png

▼注意! shaderの名前を後から変更すると…(間違い探し)

スクリーンショット 2021-02-20 20.27.51.png
右側に注目。名前がUnlit/NewUnlitShaderになってしまうので、アタッチしようとするときに名前がわかりづらい。作成直後に名前が変更できるときがあるので、ここで変更しておくとよい。
なお、Shaderのスクリプトを変更する際にスクリプト内で名前を変更すれば、こちらのInspector表示上の名前も変わる。名前の不一致に注意。

4.3 シェーダースクリプトをアタッチする

マテリアルをInspector画面に表示する。Shader>Unlit>"Shaderの名前"からアタッチできる。
スクリーンショット 2021-02-20 20.31.41.png

▼アタッチしたところ。シェーダースクリプトの中身がまだ空なのでただの画像が表示されている。
スクリーンショット 2021-02-20 20.44.55.png

4.4 シェーダースクリプトの中身(HLSL)の作成

エディタでShaderを表示し、コードを変更して保存する。
UnityのScriptを作ったときと同様に、あらかじめ書き込まれている文章があるが、特にこだわりがなければ以下のコードのコピペで構わない。

スクリプトはUnityでトランジション演出を実装する の記事から、時間によって画像のα値を増減するの項目より引用。※Unityのスクリプト同様、名前に注意すること!

"Shaderの名前"
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"
}

▼スクリプトを入力したところ。
スクリーンショット 2021-02-20 20.47.29.png

5. Shaderを動かすスクリプト(C#)の作成

C#スクリプトを作成。

スクリプトはUnityでトランジション演出を実装する の記事から、時間を制御するスクリプトの項目より引用。

▼暗転用C#スクリプト

Transition.cs
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 );
    }
}

コピペそのままでは:warning:エラーが出るので、まずオブジェクト(Image)にアタッチしてから、NoneになっているTransition In変数に、マテリアルをアタッチする。

▼スクリプトを入力し、Transition Inにマテリアルをアタッチしたところ。
スクリーンショット 2021-02-20 21.07.47.png

動かしてみると→
2021-02-20 21.13.31.gif
マテリアルの色で暗転するようになりました。

▼明転用C#スクリプト(暗転用と同様に設定)

スクリプトはUnityでトランジション演出を実装する の記事から、時間を制御するスクリプトの項目を一部改変。

Transition02.cs
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 );
    }
}

動かしてみると→
gif02.gif

6. 完成・アレンジ

マテリアルの色(Tint)を変更すると、明転・暗転の色が変わる。gif03.gif

★ルール画像を変更4すれば、いろいろな模様で暗転・明転させることができる。gif04.gif

★このスクリプトのままではStart時にCoroutineが始まってしまうので、Coroutineの開始を適宜調整する。


補記

途中でトランジションのスペル(綴り)がTransitionであることを知りました。やっちまった…


  1. uGUI (UnityのUI機能) の使い方まとめ, 2016, http://mikan-daisuki.hatenablog.com/entry/2016/01/11/175010 

  2. Unityでトランジション演出を実装する,2019, https://blog.cfm-art.net/archives/963 

  3. Unityリファレンス(Unityで使用するシェーダー言語), https://docs.unity3d.com/ja/2018.4/Manual/SL-ShadingLanguage.html 

  4. このルール画像を使っています(自作のため使用自由)Rule2.png 

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3