创建UGUI地图,每块地块(Image)上添加AreaNode脚本,根据PolygonCollider2D可视化编辑碰撞体形状,并以此生成Mesh
Mc_AreaNode脚本:
private GameObject _objPrefab; //创建的Mesh预制体
private float _canvasPosZ;
private Vector3 _scale;
public GameObject creatObj; //实例化出来的Mesh
public Material mat; //实例化的Mesh的Mat
private PolygonCollider2D _collider;
private Mesh _colliderMesh;
private List<Vector2> _currentPoints = new List<Vector2>();
private List<Vector2> _tempPoints = new List<Vector2>();
private Vector3 _currentPosition;
public void SetPrefab(GameObject prefab,float z,Vector3 scale)
{
_objPrefab = prefab;
_canvasPosZ = z;
_scale = scale;
}
public void CreatMesh(Action click=null)
{
RefreshMesh();
creatObj = Instantiate(_objPrefab);
creatObj.transform.localPosition = new Vector3(0f, 0f, _canvasPosZ - 1f);
creatObj.GetComponent<MeshCollider>().sharedMesh = _colliderMesh;
creatObj.GetComponent<MeshFilter>().mesh = _colliderMesh;
creatObj.GetComponent<Mc_AreaMesh>().SetCallBack(click);
creatObj.transform.localScale = _scale;
mat = creatObj.GetComponent<MeshRenderer>().material;
}
private void Awake()
{
_collider = GetComponent<PolygonCollider2D>();
}
private void OnDrawGizmos()
{
RefreshMesh();
if (_colliderMesh)
{
Gizmos.color = new Color32(212, 199, 21, 128);
Gizmos.DrawMesh(_colliderMesh);
Gizmos.color = Color.white;
}
}
public int GetMine()
{
return mineNum;
}
private void RefreshMesh()
{
if (!_collider) return;
bool recreateMesh = false;
do
{
if (!_colliderMesh)
{
recreateMesh = true;
break;
}
if (transform.position != _currentPosition)
{
recreateMesh = true;
_currentPosition = transform.position;
break;
}
_tempPoints.Clear();
_collider.GetPath(0, _tempPoints);
if (_tempPoints.Count != _currentPoints.Count)
{
recreateMesh = true;
_currentPoints.Clear();
_currentPoints.AddRange(_tempPoints);
break;
}
for (int i = 0; i < _tempPoints.Count; ++i)
{
if (_tempPoints[i] != _currentPoints[i])
{
recreateMesh = true;
_currentPoints.Clear();
_currentPoints.AddRange(_tempPoints);
break;
}
}
} while (false);
if (recreateMesh)
{
_colliderMesh = _collider.CreateMesh(true, true);
_colliderMesh.RecalculateNormals();
_colliderMesh.UploadMeshData(true);
}
}
生成Mesh的预制体,使用的材质球是Unlit/Color,这种材质球就不受光照影响,最开始设置为黑色
创建一个摄像机,专门照射生成的Mesh的层级,创建一个renderTexture,将摄像机设置为此RenderTexture,黑雾,创建一个Shader,当像素点为红色时,此像素点位透明,将材质球设置为黑雾(image)的材质球(点亮地块就将Mesh变为红色)
shader
Shader "Unlit/FogOfWar"
{
Properties
{
_MainTex ("Main Texture", 2D) = "white" {}
// _FogText("Fog Texture",2D) ="white" {}
_alpha("alpah",float) = 0.02
}
SubShader
{
Blend SrcAlpha OneMinusSrcAlpha
Tags
{
"Queue" = "Transparent"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
float _alpha;
// sampler2D _FogText;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
// fixed4 fogCol = tex2D(_FogText, i.uv);
//红色是走过的路径,蓝色是当前人的视野范围
// red = 1,blue=1,我们显示完全透明的黑色
// red =1,blue=0,我们显示半透明黑色,表示走过,但是现在不在这个位置
//red=0,blue=0,我们显示不透明的黑色
//任何超过一的h值都会变成1
col.a = 1-col.r;
return fixed4(0,0,0,col.a-_alpha);
}
ENDCG
}
}
}