u3d honey hex framework 路径显示改造

原始的寻路使用了一个第三方的unity3d astar库,这地图中是使用六边形的中心作为路径点,而且可通行的区域不能动态变化,所以想改造一下。

改造达到的效果是1)不使用路径点,而是每个六边形的格子里面的点都可以作为寻路的目标;2)选了不同的角色之后,可以通行的区域不同;3)能显示出可通行的区域。


自己使用a*算法重新写了寻路后,这两点都没有问题了。但是要显示出可以通行的区域就比较麻烦了,最后想了一个办法,修改了代码和shader后实现了,记录在此。

显示的效果如下:绿色部分为可以通行的区域,红色部分为不可通行的区域。当选择不同的角色之后,显示区域会实时变化。

u3d honey hex framework 路径显示改造_第1张图片


实现的方法如下:

1)为每种格子类型设定一个id,为整数,从1开始。如果有5种格子,那个id就为1到5。那么地图就由类似下面这样组成:

u3d honey hex framework 路径显示改造_第2张图片

2)在渲染的地形的时候,新建一个渲染的平面图,这个平面图也是有上面的格子构成,但是需要将格子的id转变为颜色,比如,我这里用id除以10作为颜色的红色:id1的红色值为1/10,id2的红色值为2/10,等等。然后用绿色的值作为最后显示通行区域时绿色和红色的alpha透明度。可以看到第一张图中每个格子中间,绿色和红色基本上没有了,而边缘是最浓的,就是有这个alpha值控制的。渲染下来的结果大概如下所示:颜色相同的格子属于同一个id。

u3d honey hex framework 路径显示改造_第3张图片


3)在显示可通行的区域时,将当前能通行的区域的id信息转换为一个图片,此图片的宽度为格子的种类*错误冗余值,高度为1,如下所示:

u3d honey hex framework 路径显示改造_第4张图片

4)决定地图上一个点是否能通行时,对第2步中的图中对应点采样,获取到r值和g值。r值转换回id,比如上面id转换为r值时的方法是r=id/10,那么此时转换回来就是id=r*10。

获取到id值为浮点数,有一定误差,比如本来id为2,但是转换回来可能为1.9。第3步中的错误冗余值就是为了消除这个误差的。

获取到id之后,就使用第3步中的图获取到当前id的格子能不能通行。比如:id为1.9,那么第3步中图对应的x坐标=(1.9 - 0.5) * 4=5.6,所以像素值为第6个像素和第7个像素的插值,为黑色,代表当前格子不能通行,当前点需要用红色显示,透明度为之前的g值,就能达到最开始图中的效果了。

错误冗余值就是保证r值转换为id之后,在第2步的图中采样时,即使有计算误差,采样的坐标也在正确范围之内。比如错误冗余值为4时,初始id为1时,保证转换后的id算出来的x坐标在0~3之间,初始id为2时,x坐标在4~7之间,等等。


shader代码如下:

Shader "HoneyFramework/Terrain" 
{
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _PathTex ("Path (RGB)", 2D) = "white" {}   // 第2步中的图
        _IncludeTex ("Include (RGB)", Rect) = "white" {} // 第3步中的图
        _PathColor ("Path Color", Color) = (0, 1, 0, 1) // 可通行格子的颜色,默认为绿色
        _BlockColor ("Block Color", Color) = (0.5, 0, 0, 1) // 不能通行格子的颜色,默认为红色
        _Switch ("Switch", Int) = 0 // 开关,打开时显示通行状态
        _Div ("id to color div", Int) = 10 // id转为r值时的除数,也就是说这个数为10时,id=1时,r值=0.1
        _DimTime ("dimension time", Int) = 4 // 错误冗余值
        _IncludeLen ("Include length", Int) = 10 // 第3步图的宽度,等于格子种类数量,计算时使用
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 300
            
        CGPROGRAM
        #pragma surface surf BlinnPhong addshadow fullforwardshadows nolightmap
        #pragma target 3.0
        #pragma glsl      

        struct Input {
            float2 uv_MainTex;
            float2 uv_PathTex;
        };

        sampler2D _MainTex;
        sampler2D _PathTex;
        sampler2D _IncludeTex;
        float4 _PathColor;
        float4 _BlockColor;
        int _Switch;
        int _Div;
        int _DimTime;
        int _IncludeLen;

        void surf (Input IN, inout SurfaceOutput o) {
        	half4 c = tex2D (_MainTex, IN.uv_MainTex);
        	if (0 == _Switch)
        	{
            	o.Albedo = c.rgb;
            }
            else
            {
            	half2 posInfo = tex2D (_PathTex, IN.uv_PathTex).rg;
            	half pos = posInfo.r * _Div;
            	if (pos < 0.5)
            	{
            		o.Albedo = c.rgb;
            	}
            	else
            	{
	            	pos = (pos - 0.5) * _DimTime / _IncludeLen;
	            	half flag = tex2D (_IncludeTex, float2(pos, 0)).r;

	            	half4 layerColor;

	            	if (flag > 0.9)
	            	{
	            		layerColor = _PathColor;
	            	}
	            	else
	            	{
	            		layerColor = _BlockColor;
	            	}

	            	half alpha = posInfo.g * layerColor.a;
	            	o.Albedo = layerColor.rgb * alpha + c.rgb * (1 - alpha);
            	}
            }

            o.Specular = 0.2;
            o.Gloss = 1.0;
        }
        ENDCG
    }
    FallBack "Diffuse"
}


你可能感兴趣的:(u3d honey hex framework 路径显示改造)