我的接到的需求是这样的
请看最后的效果图
我们开始
简化一下需求就是根据2个点创建宽度为width*2的带有颜色渐变的Mesh
创建一个正方形的Mesh需要四个点,而我这儿的需求是只有两个 所以我就将两点看成中心点通过一个Width来得到四个点也就是这儿。
Vector3 pos1 = nextDrawnMesh.transform.position + new Vector3(-width, 0, 0);
Vector3 pos2 = nextDrawnMesh.transform.position + new Vector3(width, 0, 0);
Vector3 pos3 = currentDrawnMesh.transform.position + new Vector3(width, 0, 0);
Vector3 pos4 = currentDrawnMesh.transform.position + new Vector3(-width, 0, 0);
可以看到他她是一个Vector3的所以这个值附在不同的位置会有不同的方向 可以自己去测试一下想要的效果
或者说自己定义四个点 不用这儿的计算 可自行赋值
所以 就有方法 addpos他就是用来添加所有的点的 addpos对应添加点了 name就有对应添加颜色 addcolor
currentDrawnMesh.SetShaderColor("_ColorTop", color);
currentDrawnMesh.SetShaderColor("_ColorMid", color);
nextDrawnMesh.SetShaderColor("_ColorBot", color);
这三个东西呢不需要了解 是Shader的属性,根须Shader的字段来的这儿踩到个坑哈,这个属性名称不是在Shader代码里属性的名称哈,要设置Shader里属性要仔细看看Shader面板下面的各个属性名称去对应一下,我一开始就拿错了,去Shader里拿代码里面的名称是修改不了的哦!
public class ProtractMeshController : MonoBehaviour
{
public static ProtractMeshController interest;
public float width = 0.002f;
public GameObject MeshPosObj;
public Color color;
private void Awake()
{
interest = this;
InitProtractMeshPos();
widthRecording = width;
}
float widthRecording ;
public void Update()
{
if(widthRecording!= width)
{
widthRecording = width;
InitProtractMeshPos();
}
}
public void AddPos(List<GameObject> pos){
for(int i=0;i< pos.Count; i++)
{
GameObject go = GameObject.Instantiate(MeshPosObj, pos[i].transform.position,Quaternion.identity);
go.transform.parent = this.transform;
}
InitProtractMeshPos();
}
public void AddColor(List<Color32> colors)
{
if (this.transform.childCount <= 0) return;
for (int i = 0; i < colors.Count; i++)
{
if (i + 1 < colors.Count)
{
DrawnMesh currentDrawnMesh = transform.GetChild(i).GetComponent<DrawnMesh>();
DrawnMesh nextDrawnMesh = transform.GetChild(i + 1).GetComponent<DrawnMesh>();
currentDrawnMesh.SetShaderColor("_ColorTop", colors[i + 1]);
currentDrawnMesh.SetShaderColor("_ColorMid", colors[i + 1]);
currentDrawnMesh.SetShaderColor("_ColorBot", colors[i]);
}
}
}
/// <summary>
/// 初始化mesh点位
/// </summary>
public void InitProtractMeshPos()
{
for (int i = 0; i < transform.childCount; i++)
{
if (i + 1 < transform.childCount)
{
DrawnMesh currentDrawnMesh = transform.GetChild(i).GetComponent<DrawnMesh>();
DrawnMesh nextDrawnMesh = transform.GetChild(i + 1).GetComponent<DrawnMesh>();
Vector3 pos1 = nextDrawnMesh.transform.position + new Vector3(-width, 0, 0);
Vector3 pos2 = nextDrawnMesh.transform.position + new Vector3(width, 0, 0);
Vector3 pos3 = currentDrawnMesh.transform.position + new Vector3(width, 0, 0);
Vector3 pos4 = currentDrawnMesh.transform.position + new Vector3(-width, 0, 0);
currentDrawnMesh.posList = new List<Vector3>() { pos4, pos3, pos2, pos1 };
currentDrawnMesh.SetMesh();
currentDrawnMesh.SetShaderColor("_ColorTop", color);
currentDrawnMesh.SetShaderColor("_ColorMid", color);
nextDrawnMesh.SetShaderColor("_ColorBot", color);
}
}
}
public void Clean()
{
for(int i = transform.childCount; i> 0; i--)
{
GameObject.Destroy(transform.GetChild(i - 1).gameObject);
}
}
}
这个就是绘制Mesh啦!要注意自己绘制的mesh要添加好UV不然材质上上去不对哦!
public class DrawnMesh : MonoBehaviour
{
public float proportion = 1f;
public List<Vector3> posList = new List<Vector3>();//赋值顺序为顺时针或者逆时针(为世界坐标位置)
public MeshRenderer meshRenderer;
public GameObject ga;
void Awake()
{
meshRenderer = GetComponent<MeshRenderer>();
}
/// <summary>
/// 设置shader的颜色属性
/// </summary>
/// <param name="attributeName"> 三种 "_ColorTop","_ColorMid","_ColorBot" </param>
/// <param name="color"></param>
public void SetShaderColor(string attributeName, Color color)
{
meshRenderer.materials[0].SetColor(attributeName, color);
}
public void SetMiddle(float value)
{
meshRenderer.materials[0].SetFloat("_Middle", value);
}
public void SetMesh()
{
List<Vector3> vertices = new List<Vector3>();
for (int i = 0; i < posList.Count; i++)
{
Vector3 pos = (posList[i] - transform.position) * proportion;
vertices.Add(pos);
}
DrawPentagon(vertices);
}
void DrawPentagon(List<Vector3> vertices)
{
Mesh mesh = new Mesh();
mesh.name = gameObject.name;
int triangleAmount = vertices.Count - 2;
int[] triangles = new int[3 * triangleAmount];
//根据三角形的个数,来计算绘制三角形的顶点顺序(索引)
//顺序必须为顺时针或者逆时针
for (int i = 0; i < triangleAmount; i++)
{
triangles[3 * i] = 0;
triangles[3 * i + 1] = i + 1;
triangles[3 * i + 2] = i + 2;
}
Vector2[] baseUVs = new Vector2[] { new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1), };
mesh.vertices = vertices.ToArray();
mesh.uv = baseUVs;
mesh.triangles = triangles;
GetComponent<MeshFilter>().mesh = mesh;
}
}
这个就是颜色对撞的shader了
Shader "Unlit/Gradient"
{
Properties
{
[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
_ColorTop("Top Color", Color) = (1, 1, 1, 1)
_ColorMid("Mid Color", Color) = (1, 1, 1, 1)
_ColorBot("Bot Color", Color) = (1, 1, 1, 1)
_Middle("Middle", Range(0.001, 0.999)) = 1
_test("Test", Range(0.001, 0.999)) = 1
}
SubShader
{
Tags {"Queue" = "Background" "IgnoreProjector" = "True"}
LOD 100
ZWrite On
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _ColorTop;
fixed4 _ColorMid;
fixed4 _ColorBot;
float _Middle;
float _test;
struct v2f
{
float4 pos : SV_POSITION;
float4 texcoord : TEXCOORD0;
};
v2f vert(appdata_full v)
{
v2f o;
if (v.vertex.y > _test)
{
v.vertex.y = _test;
}
o.pos = UnityObjectToClipPos(v.vertex);
o.texcoord = v.texcoord;
return o;
}
fixed4 frag(v2f i) : COLOR
{
fixed4 c = lerp(_ColorBot, _ColorMid, i.texcoord.y / _Middle) * step(i.texcoord.y, _Middle);
c += lerp(_ColorMid, _ColorTop, (i.texcoord.y - _Middle) / (1 - _Middle)) * step(_Middle, i.texcoord.y);
c.a = 1;
return c;
}
ENDCG
}
}
}