unity实现3D圆形血条功能

来源:互联网 发布:淘宝暗黑系服装品牌 编辑:程序博客网 时间:2024/06/05 01:39

最近需要一个3D的圆形血条功能,多方测试完成后做个简单总结。


1、上来的思路考虑NGUI实现的Fill效果,查看NGUI代码发现它的实现方式是动态修改Mesh形状实现的,所以考虑按本方案尝试一次。

动态创建圆形Mesh功能代码参考:http://blog.csdn.net/ecidevilin/article/details/52456107

shader选择用简单的混合:

float4 frag(VertexOutput i) : COLOR {float4 _MainTex_Color = tex2D(_MainTex,TRANSFORM_TEX(i.uv0, _MainTex));fixed4 finalRGBA = fixed4(_TintColor.rgb*_MainTex_Color.rgb,_MainTex_Color.a);      return finalRGBA;}


效果图                                                                                                                                      贴图

                                                  

2.实现后,考虑血条没有底色显示,同时再加一层护盾效果。如果继续按照方案一来的话,需要创建一个底层的圆形,护盾的圆形,会造成性能损耗,批次过多,所以考虑方案二,依靠shader来实现此功能,模型使用Quad即可。


shader代码:

Shader "Example/HpAndHuDun_Tex" {//属性    Properties {_RampTex ("RampTex", 2D) = "white" {}        _HpTex ("HpTex", 2D) = "white" {}_HpColor ("HpColor", Color) = (0,1,0.006896496,1)        _BottomColor ("BottomColor", Color) = (0.5215687,0.5215687,0.5215687,1)                _HpSlider ("HpSlider", Range(0, 1)) = 0.4866171        _HuDunTex ("HuDunTex", 2D) = "white" {}        _HuDunSlider ("HuDunSlider", Range(0, 1)) = 0.324226    }    SubShader {        Tags {            "IgnoreProjector"="True"            "Queue"="Transparent"            "RenderType"="Transparent"        }        LOD 100        Pass {            Name "FORWARD"            Tags { "LightMode"="ForwardBase" }            Blend SrcAlpha OneMinusSrcAlpha            ZWrite Off            CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #define UNITY_PASS_FORWARDBASE            #include "UnityCG.cginc"            #pragma multi_compile_fwdbase            #pragma target 3.0            uniform sampler2D _HpTex; uniform float4 _HpTex_ST;            uniform float4 _BottomColor;            uniform float4 _HpColor;            uniform float _HpSlider;            uniform sampler2D _RampTex; uniform float4 _RampTex_ST;            uniform sampler2D _HuDunTex; uniform float4 _HuDunTex_ST;            uniform float _HuDunSlider;//输入结构            struct VertexInput {                float4 vertex : POSITION;                float2 texcoord0 : TEXCOORD0;            };//输出结构            struct VertexOutput {                float4 pos : SV_POSITION;                float2 uv0 : TEXCOORD0;            };//顶点计算            VertexOutput vert (VertexInput v) {                VertexOutput o = (VertexOutput)0;                o.uv0 = v.texcoord0;                o.pos = mul(UNITY_MATRIX_MVP, v.vertex );                return o;            }//片段计算            float4 frag(VertexOutput i) : COLOR {//计算hp圈的uv 颜色值                float2 hpUV = ((i.uv0*1.1)+(-0.05));                float4 _HpTexColor = tex2D(_HpTex,TRANSFORM_TEX(hpUV, _HpTex));//渐变图的颜色值                float4 _RampTexColor = tex2D(_RampTex,TRANSFORM_TEX(i.uv0, _RampTex));//护盾颜色                float2 huDunUV = ((i.uv0*0.9)+0.05);                float4 _HuDunTexColor = tex2D(_HuDunTex,TRANSFORM_TEX(huDunUV, _HuDunTex));//最后hp颜色float3 finalHpColor = lerp( (_HpColor.rgb*_HpTexColor.rgb), (_HpTexColor.rgb*_BottomColor.rgb), trunc((_RampTexColor.r+(1.0-_HpSlider))));//最终颜色 混合 护盾和 hp颜色                float3 finalColor = (finalHpColor*_HpTexColor.a)+(_HuDunTexColor.rgb*_HuDunTexColor.a);float finalAlpha = _HpTexColor.a+(_HuDunTexColor.a*(1.0-trunc((_RampTexColor.r+(1.0-_HuDunSlider)))));                return fixed4(finalColor,finalAlpha);            }            ENDCG        }    }    FallBack "Diffuse"}


效果图如下 噪点图片

                                     


3. 方案二有个问题,因为用了渐变贴图和trunc方法,在边缘处有噪点,向朋友咨询提出如下方案方案二用了alpha,性能一般,考虑进一步优化。使用3D模型 + 颜色来进行处理,UV水平向展开即可。


shader关键代码:


float4 frag(VertexOutput i) : COLOR{//这步是为了省去if判断是否在范围,用扩大10000倍来处理浮点数的精度问题float colorSelect = saturate(saturate(i.uv0.x - _Progress) * 10000.0);float3 finalColor = _CircleColor.rgb * (1 - colorSelect) + _BackgroundColor.rgb * colorSelect;return fixed4(finalColor,1.0);}

效果图



最终总结,方案二,模型面数少,用了两张贴图和alpha混合,方案三不使用贴图,但是圆环如果要圆润的话,模型面数较高。具体情况自己衡量考虑。



0 0
原创粉丝点击