概要
以下のように丸を並べた点線をLineRendererで描画します。ついでにアニメーションもつけました。
プロジェクトのソースはこちら
https://github.com/Arihide/unity-dotted-line
解説
LineRendererをアタッチする
まず、適当なGameObjectにLineRendererをアタッチします。
その後、下のように[Texture Mode]を[Tile]に設定します。
シェーダーを書く
次に、LineRendererに設定する点線のマテリアルのためのシェーダーを書いていきます。
1.丸を並べる
まずは下図のように、丸を隙間なく敷き詰めるLineRenderer用のシェーダーを書きます。
どのようなロジックでこれを実現するかというと、
先程のTextureMode:Tileの設定によって、以下のようなUV座標になるので、
以下のように0...1になるように座標を変更したあと、
中心:(0.5, 0.5)、半径:0.5 の円を考えて、内側は不透明、外側は透明になるように描画してあげればよいです。
それを踏まえたシェーダーのコードは以下になります。
Shader"Custom/DottedLine"{SubShader{Tags{"RenderType"="Transparent"}BlendSrcAlphaOneMinusSrcAlphaPass{CGPROGRAM#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
structappdata{half2texcoord:TEXCOORD0;half4vertex:POSITION;fixed4color:COLOR0;};structv2f{half2uv:TEXCOORD0;half4pos:SV_POSITION;fixed4color:COLOR0;};v2fvert(appdatav){v2fo;o.pos=UnityObjectToClipPos(v.vertex);o.uv=v.texcoord;o.color=v.color;returno;}fixed4frag(v2fi):SV_TARGET{// 1の剰余をとることで、0と1の間を繰り返すようにするi.uv.x=i.uv.x%1;fixed4col=i.color;// 円の内側を不透明、外側を透明にするhalfs=length(i.uv-half2(1,1)*0.5);col.a=saturate((0.5-s)*100);returncol;}ENDCG}}}
上記のシェーダーを記述後、マテリアルを作成しLineRendererのマテリアルにアタッチすると、はじめの図のように先に沿って丸が描画されると思います。
ここで、以下のコード部分が若干複雑なので補足します。
// 円の内側を不透明、外側を透明にするhalfs=length(i.uv-half2(1,1)*0.5);col.a=saturate((0.5-s)*100);
この関数をプロットすると以下のようになります。(xy平面がそれぞれUV、z軸はアルファ値)
図を見てもらうとわかるように、円柱ではなく円錐台になっています。
このようにすることによって、円の境界線をぼかしてきれいに描画できるようになります。
円の隙間を開ける
隙間が詰まりすぎていて気になるので、次は間隔を少し開けてみます。
これは以下のように、_Spaceという変数を用意して、剰余と円の中心をずらせば実現できます。
Shader"Custom/DottedLine"{Properties{_Space("Space Between Dots",Range(1,5))=1.2}SubShader{//...(中略)half_Space;fixed4frag(v2fi):SV_TARGET{i.uv.x=i.uv.x%_Space;fixed4col=i.color;// 円の内側を不透明、外側を透明にするhalfs=length(i.uv-half2(_Space,1)*0.5);col.a=saturate((0.5-s)*100);returncol;}ENDCG}}}
変更後、マテリアルから[Space Between Dots]の値を調節することで隙間があくのを確認できます。
アニメーションさせる
これで完成でもよいのですが、せっかくなので冒頭のGifのように時間経過によって丸が動くようなアニメーションもつけたいと思います。これはとても簡単で、frag関数冒頭を
i.uv.x=(i.uv.x+_Time*50)%_Space;
と置き換えることで実現できます。見ていただけばわかるように時間ごとに座標をずらしています。
まとめ
以上、LineRendererのシェーダーで点線を描画する方法について説明しました。
シェーダーを工夫すれば、円ではなく楕円などの点線にすることもできると思うので、色々試してみるのも面白いかもしれません。