LoginSignup
12
11

More than 5 years have passed since last update.

【Unity】uGUIスプライトが砂のように消滅するシェーダーを作ってみる

Last updated at Posted at 2018-12-23

まずは作成したものからどうぞ。

VanishShader.gif

はじめに

よく、RPGなどでモンスターが死亡したときに砂のように消滅するかっこいい演出をみかけますが、その演出をシェーダーで作成してみました。

開発環境

  • Unity2018.3.0f2
  • Windows10
  • 実機動作確認
    • Android Galaxy s6 edgeにて確認。
    • ※iOSを持ってないためiOS未検証です。ご了承ください。

VanishingShader

こちらが今回作成したシェーダーのコードです。
消滅させるシェーダーなのでそのままVanishingShaderと名付けました。

VanishingShader.

Shader "Custom/VanishingShader"
{
    Properties
    {
        _MainTex ("Source", 2D) = "white" {}
        _StrengthX("StrengthX",Float) = 0
        _StrengthY("StrengthY",Float) = 0
        _Alpha("Alpha",Range(0,1)) = 1
    }

    SubShader
    {
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off
        Fog { Mode Off }
        Tags { "Queue" = "Transparent" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _StrengthX;
            float _StrengthY;
            float _Alpha;

            float rand(float2 co)
            {
                return frac(sin(dot(co.xy, float2(12.9898, 78.233))) * 43758.5453);
            }

            fixed4 frag (v2f_img i) : SV_Target
            {
                float r = rand(i.uv);
                float2 uv = i.uv + r * float2(_StrengthX, -_StrengthY);
                fixed4 c = tex2D(_MainTex, uv );
                c.a *= _Alpha;
                return c;
            }
            ENDCG
        }
    }
}

解説

シェーダーコードについて解説していきます。
まずはPropertiesからですが、これらプロパティたちをのちほど出てくる
コンポーネントからいじることになります。

    Properties
    {
        _MainTex ("Source", 2D) = "white" {}
        _StrengthX("StrengthX",Float) = 0
        _StrengthY("StrengthY",Float) = 0
        _Alpha("Alpha",Range(0,1)) = 1
    }

_Source:テクスチャを指定します。
_StrengthX:0なら何も効果なし。 値が大きくなるほど横方向に砂化します。
_StrengthY:0なら何も効果なし。値が大きくなるほど縦方向に砂化します。
_Alpha:0なら透明。値が1で不透明です。

頂点シェーダー・フラグメントシェーダーの指定

#pragma vertex vert_img
#pragma fragment frag

この部分で、頂点シェーダーにvert_imgを、フラグメントシェーダーにfragを指定しています。

vert_imgはビルドインの頂点シェーダーです。
UnityCG.cgincというビルドインの変数やヘルパー関数が定義されたファイル内に定義されています。

#include "UnityCG.cginc"

のように定義することで使用できるようになります。
今回はすでに定義された頂点シェーダーを使用したので、書いたシェーダーのコード量も減りましたが、
実際の定義を引用すると、このようになっています。

struct appdata_img
{
    float4 vertex : POSITION;
    half2 texcoord : TEXCOORD0;
    UNITY_VERTEX_INPUT_INSTANCE_ID
};

v2f_img vert_img( appdata_img v )
{
    v2f_img o;
    UNITY_INITIALIZE_OUTPUT(v2f_img, o);
    UNITY_SETUP_INSTANCE_ID(v);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

    o.pos = UnityObjectToClipPos (v.vertex);
    o.uv = v.texcoord;
    return o;
}

そしてスプライトを砂と化すメイン部分がこちらです。

float r = rand(i.uv);
float2 uv = i.uv + r * float2(_StrengthX, -_StrengthY);
fixed4 c = tex2D(_MainTex, uv );

UVをランダムに(Strengthが強いほどどんどん)ズラして、
砂みたいになるのを表現しています。

randについてはこちらランダムな値を返す関数 on GLSLを参考にしました。

テクスチャ設定について

Textureの設定のWrapModeClampにしておきます。
Repeatだと、上方に移動した砂がまた下方から表示されてきてしまうので、
見た目としておかしくなります。

マテリアルを作成する

マテリアルを作成し、シェーダーはCustom/VanishingShader を選択します。
2018-12-23_21h34_21.png

コントローラー

アニメーションからマテリアルのシェーダーのパラメータを操作できるようにします。
シェーダーのパラメータをアニメーションで制御できるようにするために、
コントローラーとなるコンポーネントを作成します。

VanishingShaderController.cs
using UnityEngine;

[ExecuteInEditMode]
public class VanishingShaderController : MonoBehaviour
{
    [SerializeField] float strengthX = 0f;
    [SerializeField] float strengthY = 0f;
    [SerializeField] float alpha = 1f;
    [SerializeField] Material material;

    void Update()
    {
        UpdateMaterial();
    }

    void UpdateMaterial()
    {
        if (material == null) { return; }

        material.SetFloat("_StrengthX", strengthX);
        material.SetFloat("_StrengthY", strengthY);
        material.SetFloat("_Alpha", alpha);
    }
}

インスペクターはこんな感じ。
2018-12-23_20h17_28.png

マテリアルをアタッチ

uGUIのImageVanishingShaderControllerMaterialにマテリアルをアタッチします。
2018-12-23_21h33_06.png

コンポーネントのインスペクターで露出している値をアニメーションのほうで制御してみましょう。

2018-12-23_20h18_02.png

こんな感じでStrengthY(もしくはX)やAlphaを制御してやれば、調整可能です。

プロジェクトデータ

今回作成したプロジェクトをGithubに載せました。
どうぞご自由にご利用ください。
https://github.com/gingerbread4/VanishingShader

まとめ

いかがでしたでしょうか。作成したシェーダーは初歩的でシンプルながら、
スプライトが砂のように消滅する感じが出ていて、
RPGなど、モンスターが死亡する演出などに使えるのではないでしょうか。

課題

よく見ると、ちょっとImageの上のほうで砂になったピクセルがImageの境界で見切れているのがわかると思います。透明になっていくことで少しごまかしがきいていると思いますが、見た目としてはあまりよろしくないです。

参考サイト様

12
11
1

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
12
11