Unity手绘Mesh实现颜色渐变

 我的接到的需求是这样的

请看最后的效果图

我们开始 

简化一下需求就是根据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
		}
		}
}

猜你喜欢

转载自blog.csdn.net/weixin_52599679/article/details/134304174