端が直線にならないHPゲージの作り方(Shader)
前回の記事では、両端の形状を維持したまま動くゲージをImageのMaskやFilledを用いて作成しました。このゲージをShaderを用いて作成しました。
Shader
作成したShaderは以下の通りです。Imageのカラー変更とImageTypeのFilledは正しく動作するようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
Shader "Unlit/Gauge" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Shift("Shift", Range(0 ,1)) = 0 } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } Cull Off Lighting Off ZWrite Off ZTest [unity_GUIZTestMode] Blend SrcAlpha OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #include "UnityCG.cginc" #include "UnityUI.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float4 col : COLOR; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; fixed4 col : COLOR; }; sampler2D _MainTex; float4 _MainTex_ST; fixed4 _Color; float _Shift; v2f vert (appdata v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.col = v.col; return o; } fixed4 frag (v2f i) : SV_Target { float s = (1 - _Shift) * 0.5; float2 coord = float2(saturate(i.uv.x + _Shift * step(s, i.uv.x)), i.uv.y); half4 col = tex2D(_MainTex, coord) * i.col; half mask = abs(step(1 - _Shift, i.uv.x) - 1); col *= mask; return col; } ENDCG } } } |
Script
適当なゲームオブジェクトにこのScriptをアタッチし、背景及びゲージ用sprite、先ほどのShaderとスライダーをアタッチすれば動きます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class HPGaugeShader : MonoBehaviour { public Sprite preBack, preGauge; public Shader shader; public GameObject preSlider; private GameObject objBack, objGauge, objSlider; private Slider slider; private Material mat; // Use this for initialization void Start () { Image img; RectTransform rect; Transform trfCanvas = GameObject.Find("Canvas").transform; objBack = new GameObject(); objBack.transform.SetParent(trfCanvas); objBack.transform.localPosition = Vector3.zero; objBack.AddComponent<CanvasRenderer>(); img = objBack.AddComponent<Image>(); img.sprite = preBack; rect = objBack.GetComponent<RectTransform>(); rect.sizeDelta = new Vector2(img.sprite.rect.width, img.sprite.rect.height); objGauge = new GameObject(); objGauge.transform.SetParent(trfCanvas); objGauge.transform.localPosition = Vector3.zero; objGauge.AddComponent<CanvasRenderer>(); img = objGauge.AddComponent<Image>(); img.sprite = preGauge; rect = objGauge.GetComponent<RectTransform>(); rect.sizeDelta = new Vector2(img.sprite.rect.width, img.sprite.rect.height); img.material = new Material(shader); mat = img.material; objSlider = Instantiate(preSlider, trfCanvas); objSlider.transform.localPosition = new Vector3(0, -50f, 0); slider = objSlider.GetComponent<Slider>(); } // Update is called once per frame void Update () { if (Input.GetMouseButton(0)) { mat.SetFloat("_Shift", slider.value); } } } |
実行結果
実行結果はこちらです。
-
前の記事
端が直線にならないHPゲージの作り方 2018.09.16
-
次の記事
Textureを合成するShader 2018.10.08
コメントを書く