あまブロ

UnityとかWebプログラミングとか

【Unity】unity-reference-viewerを公開しました

f:id:ina-amagami:20190310193923j:plain
unity-reference-viewer

以前guidを使ってアセットの参照を調べる方法を紹介しました。

これと同じことをUnity上で出来るツールを作りまして、ここ1年ほど愛用してます。
「同じこと」というのはOS側の検索機能を使うことです。

他にも似たようなツールはあるのですが、検索用キャッシュを作成する必要があったり、
プロジェクトの規模次第では検索がなかなか終わらない問題などに遭遇します。

Windowsではそこそこ時間がかかってしまうのですが、Macでは標準の検索機能であるSpotlightを使うと爆速で検索できます。
これはMacが検索用のインデックスをキャッシュしているためです。
逆に言えばインデックスの作成対象から除外されていたりすると結果がおかしくなるので、正確な検索用にGrepを使用したバージョンも用意しました。
参考:Mac で Spotlight のインデックスを再作成する方法

当初はエラーが出たり検索結果がおかしかったりしましたが、安定してきたのでgithubで公開しました。
使い方などはリンク先に記載してます!

結果表示をクリックするとProjectビューで選択される機能もついてます。

f:id:ina-amagami:20190310182558p:plain

また、フォルダを選択して実行した場合は中身が検索対象になります。
うっかり全アセット選択して実行しても途中でキャンセルできるのでご安心を。

 

【Unity】Sprite用アウトラインシェーダ

f:id:ina-amagami:20170423173042p:plain:w300

以下の記事で紹介されているシェーダを参考に、改良版を2種類作成してみました。
UnityのSprite用シェーダ(2本) · M.Ike

  • 線の色は固定、SpriteRendererでスプライトの色を変更できる(Sprites/Outline)
  • スプライトの色は固定、SpriteRendererで線の色を変更できる(Sprites/OutlineColor)

影とアウトラインの機能が両方含まれていたので、負荷を抑えるためアウトラインのみ残しています。
uGUIではOutlineコンポーネントを使えるので、SpriteRendererを使うケース専用です。

半透明や縦長、横長のスプライトだとアウトラインが綺麗に付かない場合があります。
アウトラインを別画像として作る方法が使えるケースでは使わない方が良いかもしれません。
 

準備:スプライト設定

Sprite Mode -> Mesh Typeを「Tight」にしている場合、
ワイヤフレームで見た時に上のUnityロゴはこんな感じになっています。

f:id:ina-amagami:20170423173138p:plain:w300

今回のシェーダでは線を描く範囲を確保するためにポリゴン内のテクスチャを縮小するため、
画像のようにポリゴンが分離している場合は変な方向にずれて縮小されてしまいます。
Mesh Typeを「Full Rect」に変更すると四角形のポリゴンになるため、アウトラインが綺麗に付くようになります。
ただし、余白部分まで描画処理が発生する分、負荷が高くなる点に注意して下さい。
 

Sprites/Outline

SpriteRendererで指定するColorは、スプライトの色に影響し、線の色には影響しません。

プロパティ

Outline Spread…線の太さ
Outline Color…線の色(アルファ値は無効)
Outline Smoothness…線のなめらかさ

実装(SpritesOutline.shader)
Shader "Sprites/Outline"
{
    Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
        _OutLineSpread ("Outline Spread", Range(0, 0.1)) = 0
        _OutLineColor ("Outline Color", Color) = (1, 1, 1, 1)
        _Smoothness ("Outline Smoothness", Range(0, 0.5)) = 0.1
    }

    SubShader
    {
        Tags
        { 
            "Queue"="Transparent" 
            "IgnoreProjector"="True" 
            "RenderType"="Transparent" 
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        Cull Off
        Lighting Off
        ZWrite Off
        Fog { Mode Off }
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile DUMMY PIXELSNAP_ON
            #include "UnityCG.cginc"
            
            struct appdata
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };
            
            sampler2D _MainTex;
            half _OutLineSpread;
            fixed4 _OutLineColor;
            fixed _Smoothness;

            v2f vert(appdata IN)
            {
                fixed scale = 1 + _OutLineSpread * 2;

                float2 tex = IN.texcoord * scale;
                tex -= (scale - 1) / 2;

                v2f OUT;
                OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
                OUT.texcoord = tex;
                OUT.color = IN.color;
                #ifdef PIXELSNAP_ON
                OUT.vertex = UnityPixelSnap (OUT.vertex);
                #endif

                return OUT;
            }

            sampler2D _AlphaTex;
            float _AlphaSplitEnabled;

            fixed4 SampleSpriteTexture (float2 uv)
            {
                fixed4 color = tex2D (_MainTex, uv);

#if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
                if (_AlphaSplitEnabled)
                {
                    color.a = tex2D (_AlphaTex, uv).r;
                }
#endif

                return color;
            }

            fixed4 frag(v2f IN) : SV_Target
            {
                fixed4 base = SampleSpriteTexture(IN.texcoord) * IN.color;

                fixed4 out_col = _OutLineColor;
                out_col.a = 1;
                half2 line_w = half2(_OutLineSpread, 0);
                fixed4 line_col = SampleSpriteTexture(IN.texcoord + line_w.xy)
                                + SampleSpriteTexture(IN.texcoord - line_w.xy)
                                + SampleSpriteTexture(IN.texcoord + line_w.yx)
                                + SampleSpriteTexture(IN.texcoord - line_w.yx);
                out_col *= line_col.a;
                out_col.rgb = _OutLineColor.rgb;
                out_col = lerp(base, out_col, max(0, sign(_OutLineSpread)));

                fixed4 main_col = base;
                main_col = lerp(main_col, out_col, (1 - main_col.a));
                main_col.a = IN.color.a * max(0, sign(main_col.a - _Smoothness));
                return main_col;
            }
        ENDCG
        }
    }
}

 

Sprites/OutlineColor

アウトラインの色はSpriteRendererのColorで指定します。

実装(SpritesOutlineColor.shader)
Shader "Sprites/OutlineColor"
{
    Properties
    {
        [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
        _Color ("Tint", Color) = (1,1,1,1)
        [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
        _OutLineSpread ("Outline Spread", Range(0, 0.1)) = 0
        _Smoothness ("Outline Smoothness", Range(0, 0.5)) = 0
    }

    SubShader
    {
        Tags
        { 
            "Queue"="Transparent" 
            "IgnoreProjector"="True" 
            "RenderType"="Transparent" 
            "PreviewType"="Plane"
            "CanUseSpriteAtlas"="True"
        }

        Cull Off
        Lighting Off
        ZWrite Off
        Fog { Mode Off }
        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
        CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile DUMMY PIXELSNAP_ON
            #include "UnityCG.cginc"
            
            struct appdata
            {
                float4 vertex   : POSITION;
                float4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex   : SV_POSITION;
                fixed4 color    : COLOR;
                float2 texcoord : TEXCOORD0;
            };
            
            sampler2D _MainTex;
            fixed4 _Color;
            half _OutLineSpread;
            fixed _Smoothness;

            v2f vert(appdata IN)
            {
                fixed scale = 1 + _OutLineSpread * 2;

                float2 tex = IN.texcoord * scale;
                tex -= (scale - 1) / 2;

                v2f OUT;
                OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
                OUT.texcoord = tex;
                OUT.color = IN.color;
                #ifdef PIXELSNAP_ON
                OUT.vertex = UnityPixelSnap (OUT.vertex);
                #endif

                return OUT;
            }

            sampler2D _AlphaTex;
            float _AlphaSplitEnabled;

            fixed4 SampleSpriteTexture (float2 uv)
            {
                fixed4 color = tex2D (_MainTex, uv);

#if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
                if (_AlphaSplitEnabled)
                {
                    color.a = tex2D (_AlphaTex, uv).r;
                }
#endif

                return color;
            }

            fixed4 frag(v2f IN) : SV_Target
            {
                fixed4 base = SampleSpriteTexture(IN.texcoord);
                base.rgb *= _Color.rgb;

                fixed4 out_col = IN.color;
                out_col.a = 1;
                half2 line_w = half2(_OutLineSpread, 0);
                fixed4 line_col = SampleSpriteTexture(IN.texcoord + line_w.xy)
                                + SampleSpriteTexture(IN.texcoord - line_w.xy)
                                + SampleSpriteTexture(IN.texcoord + line_w.yx)
                                + SampleSpriteTexture(IN.texcoord - line_w.yx);
                out_col.a *= line_col.a;
                out_col = lerp(base, out_col, max(0, sign(_OutLineSpread)));

                fixed4 main_col = base;
                main_col = lerp(main_col, out_col, (1 - main_col.a));
                main_col.a = IN.color.a * max(0, sign(main_col.a - _Smoothness));
                return main_col;
            }
        ENDCG
        }
    }
}

 
 

SublimeText3をUnityシェーダのエディタにする方法

Unityシェーダを書く時、MonoDevelopはハイライトはしてくれるけどインテリセンスは効かない。
Xamarinはハイライトすらしてくれない。
SublimeText3がお手軽に神エディタ化してくれたのでご紹介します。

ダウンロードはこちら
Sublime Text - Download

Package Controlが必要です。まだ入れていない方はこちらの記事が参考になります
[tips][Sublime Text] Sublime Text 3をインストールしたらまずやること

パッケージのインストール

MacならCommand+Shift+PでInstall Packageを立ち上げます

f:id:ina-amagami:20170407224710p:plain:w400

Unity Shaderで検索したら、
『Unity Shader』と『Unity3D Shader Highlighter and Snippets』の2種類が見つかりました。
後者があれば十分だと感じたので、こちらを紹介します!

Unity3D Shader Highlighter and Snippets

f:id:ina-amagami:20170407225627p:plain:w400
View->Syntaxで『Unity Compute Shader』と『Unity Shader』が選択可能

Compute Shaderの方はコンピュートシェーダ用だと思われるので試していませんが、
Unity Shaderはこんな感じにインテリセンスが効きます

f:id:ina-amagami:20170407225819p:plain:w400

ビルトイン関数なら右の方にbuiltin-functionと表示してくれたりなど、便利!