もくじ
はじめに
前回の記事「 【Unity Shader Graph】おすすめチュートリアルビデオ」ではShader Graphを学習する際におすすめのチュートリアルビデオを紹介しました。今回は簡単なShader Graphの使い方を紹介します。
当ブログ記事「 【Unity 2Dゲーム入門】2Dアクションゲームを作る(1/3)」で紹介した2Dアクションゲームをサンプルとして使い、Shader Graphで背景をスクロールさせるエフェクトを追加したいと思います。
実は以前作成した2Dゲームの背景スクロールは既にC#スクリプトを使用して実装済みです。スクリプトを使った背景スクロールの仕組みはとても単純なものです。
2枚の背景を並べて横に動かして一定の位置まで到達したら、また最初の位置に戻すというものをC#スクリプトで実装しています。( 1.1)
参考に背景スクロールのコードを載せておきます。
using UnityEngine;
public class BackgroundController : MonoBehaviour
{
[SerializeField] float scrollSpeed = 0.1f;
void Update()
{
transform.Translate(-scrollSpeed, 0f, 0f);
if (transform.localPosition.x < -20f)
{
transform.localPosition = new Vector3(20f, 0f, 10f);
}
}
}
本記事では、このC#スクリプトを使った背景スクロールをShader Graphで置き換えてみたいと思います。
Shader Graphで背景スクロール(準備)
Shader Graphのセットアップですが、現行のUnityバージョン(2021、2022以上)をインストールしてURPのプロジェクトを作成すればShader Graphも一緒にインストールされます。今回、UnityのバージョンはUnity 2022.2.14f1を使用しています。
Sprite Lit Shader Graphアセットの作成
背景イメージには2DのSpriteを利用しますので、まずSprite Lit Shader Graphを作成します。ProjectウィンドウのAssetsフォルダ内を右クリックしてメニューから「Create > Shader Graph > URP > Sprite Lit Shader Graph」を選択します。( 1.2, 1.3)
Materialの作成
次にシェーダーを適用するためのマテリアルファイルを作成します。作成したShader Graphアセットを選択した状態で右クリックメニューを表示させて「Create > Material」を選択します。( 1.4)
作成したShader GraphアセットやMaterialはBackgroundScroll等の名前に変更します。
背景用Spriteのインポート
背景スクロール用のSpriteを用意します。16x16ピクセルサイズの画像をUnityにインポートして2D Spriteの設定をします。細かい手順は省きますが、インポートしたSpriteについてInspectorで変更するパラメータの設定値を下記に記載しておきます。( 1.5)
- Pixels Per Unit: 16(インポートしたSpriteのサイズに合わせる)
- Mesh Type: Full Rect
- Filter Mode: Point (no filter)
- Max Size: 32
- Compression: None
インポートして設定変更したSpriteをSceneウィンドウにドラッグ&ドロップでゲームオブジェクト化します。( 1.6)
その後、先ほど、作成したMaterialファイルの「BackgroudScroll」をSprite RendererのMaterialとしてアタッチします。( 1.7)
Shader GraphのMaterialをアタッチすると背景スプライトはグレーとなり、Spriteが未設定状態となります。ここまでの手順でShader Graphのビジュアルエディタでノードを編集できる準備が整いました。( 1.8)
1.8 Shader Graph Materialの適用後のスプライト
Shader Graphで背景スクロール(エディタ)
Shader Graphアセットをダブルクリックして、ビジュアルエディタを開きます。最初に開くとVertexノードとFragmentノードだけが見えると思います。ここにいくつかのノードを追加していきます。また、変数はBlackboardで設定します。( 1.9)
Texture 2D AssetとSample Texture 2Dノード
まず、Sprite表示させるための「Texture 2D Asset」ノードを追加して、さらに「Sample Texture 2D」ノードを追加し繋ぎます。
「Texture 2D Asset」ノードにはTextureとして背景イメージ用のSpriteをアタッチしておきます。「Sample Texture 2D」ノードの「RGBA」と「Fragment」ノードの「Base Color」、「Sample Texture 2D」ノードの「A」と「Fragment」ノードの「Alpha」を繋ぎます。「Sample Texture 2D」ノードの「Sampler」スロットに「Sampler State」ノードをつなげておきます。( 1.10)
Tiling And OffsetとTimeノード
「Sample Texture 2D」ノードのUVスロットに「Tiling And Offset」ノードをつなぎます。「Tiling And Offset」ノードのOffsetスロットのXを操作するとプレビューのイメージが左右に移動するのが分かると思います。このOffsetのX値を操作できるようにノードを追加します。
横にスクロールさせる動きを付けたいので、「Time」ノードを追加します。移動速度を調整したいのでFloatノードを追加してTimeノードのTimeスロットとMultiplyノードをつなげます。続けてVector2ノードを追加しXスロットとつなげて、Outスロットを「Tiling And Offset」ノードのOffsetのXスロットとつなげます。Floatノードの値を設定するとスクロールアニメーションが開始されます。基本的な設定は以上です。( 1.11)
1.11 Tiling And OffsetとTimeノード
ノードの変数化
インスペクターでいくつかの要素を外から操作したいので、変数として設定します。Texture 2D AssetノードとTimeにつなげてるFloatノードを変数化します。変数化したいノードをそれぞれ右クリックしてメニューから「Convert To -> Property」を選択します。( 1.12)
Blackboardパネルに出現するので、名前をGraph Inspectorパネルで適宜修正しておきます。Texture 2D Assetの方は、一応定番のMainTexという名前に変更しておきます。( 1.13)
スプライトのタイル設定
背景イメージとして使用しているSpriteは16x16ピクセルサイズのため画面全体を覆っていません。これはSpriteのタイル機能を使って解決します。Hierarchyから背景イメージのゲームオブジェクトを選択し、InspectorでSprite Rendererのパラメータを以下の通り変更します。背景イメージがタイル状になり画面全体に広がります。背景イメージが前に表示されている場合は、Order in Layerでマイナスの大きな値を設定すると後ろに表示されます。( 1.14, 1.15)
Sprite Renderer Inspector Settings
- Draw Mode: Tiled
- Size Width: 20
- Height: 12
Sampler Stateノード
背景がアンチエイリアスがかかってぼやけているように見える場合があります。これはShader Graphの「Sampler State」ノードのFilterを「Point」に変更するとぼやけていない表示になります。( 1.16)
まとめ
以下は背景スクロールのShader Graph適用後のゲームデモビデオとなります。今回取り上げていないBloomエフェクトなども含んだデモになっています。( 1.17)
Shader Graph Demo ※サウンドあり
実際のところ、スクロールさせるだけであれば、スクリプトで動かしているのと大差はないのですが、Shader Graphの場合、さらに何か別のエフェクトを加えたいなというときにいくつかノードを追加するだけで、エフェクトの見た目をがらっと変えることができるので、そういうところが利点かなと思います。
今回追加したShader Graphのアセットが含まれたサンプルプロジェクトはGitHubで公開しています。
GitHub: https://github.com/51n1/My_VVVVVV
また、WebGLのデモアプリもこちらのページで公開していますので、ぜひ試してみてください。
WebGLデモ: 【Unity 2Dゲーム】VVVVVVスタイル・ゲームプロトタイプ
余談
Shader Graphの作成完了後、WebGLで出力してみたのですが、スクロールが継続しないで1回で終了してしまいました。UVスクロールの反復がうまくいかないようでした。Unity Editor上でのゲームプレイ時や、Windowsアプリのビルド実行時は問題ありませんでした。切り分けのためにテスト用プロジェクトを作成して2時間ぐらい格闘した結果、わかりました。テクスチャとして使用していたSpriteのImport SettingsのInspectorにあるWrap ModeをRepeatにする必要がありました。Unity Editorでの実行であれば、デフォルトのClampのままでもUVスクロールするのですが、WebGLではこの設定を見ているらしいですね。悩ましい。( 1.18)