unity实现3D圆形血条功能

最近需要一个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;
}


效果图                                                                                                                                      贴图

unity实现3D圆形血条功能_第1张图片                                                   unity实现3D圆形血条功能_第2张图片

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"
}


效果图如下 噪点图片

unity实现3D圆形血条功能_第3张图片                                     unity实现3D圆形血条功能_第4张图片


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);
}

效果图

unity实现3D圆形血条功能_第5张图片


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



你可能感兴趣的:(unity功能)