Making a resizable bar with moving texture + rounded corners

I want to make a progress bar that has an animated texture (like a standard progress bar), is resizable, and has rounded corners.

Each one by itself is not really that difficult. You can easily make something have rounded corners + scaleable by using a 9-sliced graphic.

A moving texture is also not hard on it’s own. You can easily scroll the UVs and the texture will move.

But, I don’t see how you can make a bar that has all 3 of those properties.

I feel like my best bet is to just have a rectangular mesh with scrolling UVs and then some kind of mask texture (that has the rounded corners) that I combine in a shader. I tried to make one in the Strumpy Shader Editor but didn’t have much luck getting any alpha to work (my resulting texture was never transparent).

I wouldn’t mind trying to write the shader myself (if that is the best way to do it) but I’m kind of at a loss as to how to even start. Most of the examples I’m seeing online are written for the fixed function pipeline and from what I’ve read the performance on those is terrible on current gen mobile devices. Tips?

Sounds like you want something like this. There’s a slot for the base texture (which scrolls) and a slot for the alpha mask texture (which doesn’t scroll) and scroll speed values.

You might need to add some functionality if you don’t want the base texture to stretch when you stretch the 9-slice sprite (a second UV set maybe, or set the base UVs in world space).

Shader "Diffuse Scroll Transparent Mask"
{

	Properties
	{
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_AlphaTex ("Mask (RGB)", 2D) = "white" {}
		_ScrollU ("Scroll Speed U", float) = 1
		_ScrollV ("Scroll Speed V", float) = 1
	}
	
	CGINCLUDE		
	
	struct v2f_full
	{
		float4 pos : SV_POSITION;
		half4 uv : TEXCOORD0;
	};
		
	#include "UnityCG.cginc"		
	
	sampler2D _MainTex;
	sampler2D _AlphaTex;
	float _ScrollU;
	float _ScrollV;
							
	ENDCG
	
	SubShader
	{
		Tags { "RenderType" = "Transparent" }
		LOD 200
		ZWrite Off
		Blend SrcAlpha OneMinusSrcAlpha
		
		Pass
		{
			Tags { "LightMode" = "Vertex" }
			
			CGPROGRAM
	
			half4 _MainTex_ST;
			half4 _AlphaTex_ST;
			
			v2f_full vert (appdata_full v)
			{
				v2f_full o;
				o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
				o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
				o.uv.zw = TRANSFORM_TEX(v.texcoord, _AlphaTex);
				
				o.uv.x += frac(_Time * _ScrollU);
				o.uv.y += frac(_Time * _ScrollV);
				
				return o; 
			}		
			
			fixed4 frag (v2f_full i) : COLOR0 
			{
				fixed4 tex = tex2D (_MainTex, i.uv.xy);
				fixed3 texAlpha = tex2D (_AlphaTex, i.uv.zw).rgb;
				tex.a = texAlpha;
				
				return tex;
			}	
			
			#pragma vertex vert
			#pragma fragment frag
			#pragma fragmentoption ARB_precision_hint_fastest 
		
			ENDCG
		}
	}

Fallback "Mobile/Texture"
}