Chapter 32無料公開

🍍 画面遷移の実装(前半)

かもそば
かもそば
2021.03.20に更新

このチャプターでは、画面遷移の実装方法を解説します。

前半では、ShaderGraphをポストエフェクトとして利用して、C#で制御する方法を紹介します。
後半では、様々な画面遷移演出を紹介します。

このチャプターで得られるもの

  • ShaderGraphをポストエフェクトとして利用する方法
  • C#とShaderGraphの連携方法

実装の流れ

  1. RendererFeatureスクリプトの作成(C#)
  2. ForwardRendererアセットへRendererFeatureを登録
  3. ShaderGraphの作成・マテリアル化
  4. マテリアルをForwardRendererアセットへ登録
  5. C#スクリプトからマテリアルのパラメータを変化させる

STEP1 : PostEffect用のC#スクリプトを追加

以下のC#スクリプトをプロジェクトに追加します。
以下のスクリプトを追加することで、 MyPostEffect が利用可能になります。

MyPostEffect.cs
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class MyPostEffect : ScriptableRendererFeature
{
    [SerializeField] private GrayscaleSetting settings = new GrayscaleSetting();
    private GrayScalePass scriptablePass;

    public override void Create()
    {
        if (settings.material != null)
        {
            scriptablePass = new GrayScalePass();
            scriptablePass.postEffectMaterial = settings.material;
            scriptablePass.renderPassEvent = settings.renderPassEvent;
        }
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        if (scriptablePass != null && scriptablePass.postEffectMaterial != null)
        {
            // レンダーキューに登録 (ポストエフェクト実行)
            renderer.EnqueuePass(scriptablePass);
        }
    }
    
    
    [System.Serializable]
    public class GrayscaleSetting
    {
        // ポストエフェクトに使用するマテリアル
        public Material material;
        
        // レンダリングの実行タイミング
        public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingTransparents;
    }

    /// <summary>
    /// Grayscale実行Pass
    /// </summary>
    class GrayScalePass : ScriptableRenderPass
    {
        private readonly string profilerTag = "GrayScale Pass";

        public Material postEffectMaterial; // グレースケール計算用マテリアル

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            var cameraColorTarget = renderingData.cameraData.renderer.cameraColorTarget;

            // コマンドバッファ
            var cmd = CommandBufferPool.Get(profilerTag);

            // マテリアル実行
            cmd.Blit(cameraColorTarget, cameraColorTarget, postEffectMaterial);

            context.ExecuteCommandBuffer(cmd);
        }
    }
}

STEP2 : RendererFeatureの編集

STEP1 で追加した My Post Effect を Unityの描画パスに登録します。

URPテンプレートでUnityプロジェクトを作成した場合、ForwardRenderer.asset というアセットが自動で作られているので、これを編集します。

Add Renderer Featureボタンから、My Post Effect を登録します。

このMy Post Effect にマテリアルを登録することで、ポストエフェクトが画面に適用されるようになります

STEP3 : ポストエフェクト用ShaderGraphの作成

AlphaClipを有効にする

GraphInspectorのGraphSettingsから、Alpha Clip のチェックボックスをONにします。

プロパティの作成

シェーダーグラフにFloatプロパティを作成します。
プロパティの名前(Name)はProgress、Referenceは _Progress とします。
_Progress というテキストはプログラムからシェーダープロパティを書き換える際に必要な情報になります。

ShaderGraphのノード構成

以下のようなシェーダーグラフを作成します。

STEP4 : マテリアルの登録

先ほどForwardRendererアセットにMy Post Effectを登録しました。
たった今作ったシェーダーグラフからマテリアルを作成、My Post Effect 上にマテリアルを登録します。

マテリアルのProgressというパラメータを変更すると、以下のようになります。

次に、ShaderGraph上で作成したプロパティ _Progress をC#プログラムから変更してみます。

STEP5 : C#でシェーダープロパティを制御

以下はマテリアルの _Progress プロパティを0から1まで変化させるC#スクリプトです。

TransitionPostEffect.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TransitionPostEffect : MonoBehaviour
{
    [SerializeField] private Material postEffectMaterial; // 画面遷移ポストエフェクトのマテリアル
    [SerializeField] private float transitionTime = 2f; // 画面遷移の時間
    private readonly int _progressId = Shader.PropertyToID("_Progress"); // シェーダープロパティのReference名

    /// <summary>
    /// 開始時に実行
    /// </summary>
    void Start()
    {
        if (postEffectMaterial != null)
        {
            StartCoroutine(Transition());
        }
    }

    /// <summary>
    /// 画面遷移
    /// </summary>
    IEnumerator Transition()
    {
        float t = 0f;
        while (t < transitionTime)
        {
            float progress = t / transitionTime;
            
            // シェーダーの_Progressに値を設定
            postEffectMaterial.SetFloat(_progressId, progress);
            yield return null;

            t += Time.deltaTime;
        }
        
        postEffectMaterial.SetFloat(_progressId, 1f);
    }
}

上記のTransitionPostEffectコンポーネントをシーン上の適当なオブジェクトにアタッチします。
インスペクターのPost Effect Materialの部分には、今回のShaderGraphのマテリアルをアタッチします。

結果

シーンを再生すると、円が広がるような画面遷移が行われます。