u3d 批量 SpriteRenderer 转换mesh源码工具下载

总调:代码 顶点创建+动态保存mesh资源+材质资源+树形结构复制

无独有偶,unity3d 2d项目用的是SpriteRenderer,因为Laya是无法支持的,所以需要转换成mesh
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

因为层级缩放会影响物体的大小,还要复制树形结构

如何使用?
选择物体父对象后选择第一个按钮
在这里插入图片描述

以后为VIP代码内容,

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;





public class SpritesToMesh : Editor
{
    static bool LogTreePath = false;
    static NodeListView m_NodeListView = new NodeListView();
    /// <summary>
    /// 选中对象后通过顶部菜单进行批量转换
    /// </summary>
    [MenuItem("JieTools/SpritesToMesh")]
    static void Do()
    {
        //获取所有的SpriteRender

        var g = Selection.activeGameObject;
        var spriteRenderers = new List<SpriteRenderer>();

        foreach (Transform t in g.GetComponentsInChildren<Transform>())
        {


            var sp = t.GetComponent<SpriteRenderer>();
            if (sp != null)
            {
                spriteRenderers.Add(sp);
            }

        }


        var d = g.GetComponent<NodeListView>();

        //创建树形结构
        foreach (var item in spriteRenderers)
        {
            CreateTree(item.gameObject);
        }

    }

    [MenuItem("JieTools/SpritesToMesh2")]
    static void Do2()
    {
        var g = Selection.activeGameObject;

        GenerateFormSprite(g.GetComponent<SpriteRenderer>(), new GameObject());
    }

    static void CreateTree(GameObject node)
    {

        List<NodeData> path = GetFullPath_List(node.transform);



        var fullpath = Path2String(path);


        if (path != null)
        {
            Transform parent = null;
            //  Transform rootTs = null;
            for (int i = 0; i < path.Count; i++)
            {

                if (i == 0)
                {
                    var rootGo = GameObject.Find("Laya_" + path[i]);
                    if (rootGo == null)
                    {
                        parent = new GameObject("Laya_" + path[i]).transform;
                    }
                    else
                    {
                        parent = rootGo.transform;
                    }
                }
                else
                {

                    if (path[i].nodeName == "c")
                    {
                        Debug.Log("ddd");
                    }
                    var curNode = GetChildExt(parent, path[i].idx);

                    if (curNode == null)
                    {
                        curNode = new GameObject(path[i].nodeName).transform;
                        //  Debug.Log(curNode.name);
                        curNode.transform.SetParent(parent);

                        curNode.transform.localPosition = path[i].localPosition;
                        curNode.transform.localRotation = path[i].localRotation;

                        curNode.transform.localScale = path[i].localScale;
                        //curNode.transform.localScale = Vector3.one;
                        parent = curNode.transform;
                        //  Debug.Log("parent"+parent.name);


                        //var mat = CreatMatExt(path[i].sp);

                        //if (mat)
                        //{
                        //    CreatMesh(curNode.gameObject, mat);
                        //    //4倍缩放才和sprite一致
                        //    //curNode.transform.localScale *= 4;
                        //}
                        CreatMatAndMesh(path[i].sp, curNode.gameObject);
                    }
                    else
                    {
                        parent = curNode.transform;
                    }
                }

            }
        }

    }

    static string Path2String(List<NodeData> path)
    {
        var s = "";
        foreach (var item in path)
        {
            s += item.nodeName + "/";
        }

        if (LogTreePath)
            Debug.Log(s);
        var s1 = "";
        foreach (var item in path)
        {
            s1 += item.idx + "/";
        }
        //Debug.Log(s1);
        return s;
    }

    private static Transform GetChildExt(Transform t, int idx)
    {

        // Debug.Log(t.name + " " + idx);
        for (int i = 0; i < t.childCount; i++)
        {
            if (i == idx)
                return t.GetChild(idx);
        }

        return null;
    }

    private static string GetFullPath(UnityEngine.Transform obj)
    {
        if (obj.parent == null) return obj.name;
        var org = obj;
        var parent = obj.parent;
        var l = new List<Transform>();
        l.Add(parent);
        while (obj.parent != null)
        {
            l.Add(obj.parent);
            obj = obj.parent;
        }

        var p = "";
        for (int i = l.Count - 1; i > 0; i--)
        {
            p += l[i].name + "/";
        }

        p += org.name;
        return p;

    }

    private static List<NodeData> GetFullPath_List(Transform p_node)
    {
        if (p_node.parent == null) return null;

        //  var parent = node.parent;
        var l = new List<NodeData>();

        var n = new NodeData() { nodeName = p_node.name, idx = GetChildIdx(p_node.parent, p_node) };
        n.SetTransformInfo(p_node);
        l.Add(n);
        // Debug.Log(p_node.name);
        Transform curNode = p_node.parent;

        while (true)
        {


            if (curNode != null)
            {
                if (curNode.parent != null)
                {
                    // Debug.Log(curNode.name);
                    n = new NodeData() { nodeName = curNode.name, idx = GetChildIdx(curNode.parent, curNode) };
                    n.SetTransformInfo(curNode);
                    l.Add(n);

                    curNode = curNode.parent;
                }
                else
                {
                    n = new NodeData() { nodeName = curNode.name, idx = -1 };
                    n.SetTransformInfo(curNode);

                    l.Add(n);
                    break;
                }
            }
            else
            {
                break;
            }



        }

        l.Reverse();


        return l;
    }

    static int GetChildIdx(Transform p, Transform obj)
    {
        for (int i = 0; i < p.childCount; i++)
        {
            if (p.GetChild(i) == obj) return i;
        }

        return -1;
    }


    static void CreatMesh(GameObject sp, Material mat)
    {
        var ms = sp.AddComponent<MeshRenderer>();

        var d = sp.AddComponent<MeshFilter>();
        d.mesh = Resources.Load<GameObject>("Quad").GetComponent<MeshFilter>().sharedMesh;

        ms.material = mat;

    }
    static Material CreatMat(SpriteRenderer sp)
    {
        if (sp && sp.sprite)
        {
            // Debug.Log(sp.sprite.name);
            return CreatMatAsset(sp.sprite.name, sp.color);



        }

        return null;

    }

    static Material CreatMatAsset(string name, Color color)
    {
        //给texture添加一张png图片                              图片的路径                            图片的类型
        //texture = AssetDatabase.LoadAssetAtPath("Assets/Texture/down.png", typeof(Texture2D)) as Texture2D;
        //创建mat
        //var mat = new Material(Shader.Find("LayaAir3D/Mesh/BlinnPhong"));
        //mat的texture
        //mat.mainTexture = texture;
        //创建的mat材质放到Assets文件夹下
        //AssetDatabase.CreateAsset(mat, "Assets/LayaMat/"+ name + ".mat");
        var mat = AssetDatabase.LoadAssetAtPath<Material>("Assets/LayaMat/" + name + ".mat");
        if (mat == null)
        {
            AssetDatabase.CopyAsset("Assets/LayaMat/_TrasnsparentMat.mat", "Assets/LayaMat/" + name + ".mat");
        }

        AssetDatabase.SaveAssets();

        AssetDatabase.Refresh();
        if (mat == null)
        {
            mat = AssetDatabase.LoadAssetAtPath<Material>("Assets/LayaMat/" + name + ".mat");

        }
        else
        {
            mat.color = color;
        }

        var texture = AssetDatabase.LoadAssetAtPath<Texture>("Assets/LayaTexture/" + name + ".PNG");
        if (texture == null)
        {
            Debug.LogError("找不到图片" + "Assets/LayaTexture/" + name + ".PNG");
        }
        mat.SetTexture("_MainTex", texture);

        return mat;
    }


    static void GenerateFormSprite(SpriteRenderer _spriteRenderer, GameObject gameObject)
    {
        //sprite的三角形数组
        ushort[] triangles0 = _spriteRenderer.sprite.triangles;
        //mesh的三角形数组
        int[] meshTriangles = new int[triangles0.Length];
        //mesh的三角形顶点
        Vector3[] vertices0 = new Vector3[_spriteRenderer.sprite.vertices.Length];
        //存储顶点数组
        for (int i = 0; i < _spriteRenderer.sprite.vertices.Length; i++)
        {
            vertices0[i] = new Vector3(_spriteRenderer.sprite.vertices[i].x, _spriteRenderer.sprite.vertices[i].y, 0);
        }
        //存储三角形数组
        for (int i = 0; i < meshTriangles.Length; i += 3)
        {
            meshTriangles[i] = triangles0[i];
            meshTriangles[i + 1] = triangles0[i + 1];
            meshTriangles[i + 2] = triangles0[i + 2];
            // yield return new WaitForSeconds(0.02f);
            // Debug.DrawLine(vertices0[meshTriangles[i]], vertices0[meshTriangles[i + 1]], Color.red, 100.0f);
            //Debug.DrawLine(vertices0[meshTriangles[i + 1]], vertices0[meshTriangles[i + 2]], Color.red, 100.0f);
            // Debug.DrawLine(vertices0[meshTriangles[i + 2]], vertices0[meshTriangles[i]], Color.red, 100.0f);
        }
        //存储sprite的texture
        Texture2D texture = _spriteRenderer.sprite.texture;
        //生成一个新的物体挂载mesh组件
        GameObject go = new GameObject();
        MeshFilter meshFilter = go.AddComponent<MeshFilter>();
        MeshRenderer meshRenderer = go.AddComponent<MeshRenderer>();
        Mesh _mesh = new Mesh();
        meshFilter.mesh = _mesh;

        //给mesh赋值
        _mesh.vertices = vertices0;
        _mesh.uv = _spriteRenderer.sprite.uv;
        _mesh.triangles = meshTriangles;

        //设置物体位置,名字等
        go.name = "MeshSprite";
        go.transform.position = gameObject.transform.position;
        go.transform.localScale = gameObject.transform.localScale;
        go.transform.rotation = gameObject.transform.rotation;

        //设置mesh的属性
        meshRenderer.material = _spriteRenderer.sharedMaterial;
        meshRenderer.sharedMaterial.mainTexture = texture;
        meshRenderer.sharedMaterial.color = _spriteRenderer.color;
        meshRenderer.sortingLayerName = _spriteRenderer.sortingLayerName;
        meshRenderer.sortingLayerID = _spriteRenderer.sortingLayerID;
        meshRenderer.sortingOrder = _spriteRenderer.sortingOrder;
        //销毁原Sprite
        DestroyImmediate(gameObject);


        AssetDatabase.CreateAsset(meshRenderer.material, "Assets/LayaMatExt/" + _spriteRenderer.sprite.name + ".mat");
        AssetDatabase.SaveAssets();

        AssetDatabase.Refresh();
    }


    //static void GenerateFormSpriteExt_Backup(SpriteRenderer _spriteRenderer, GameObject gameObject, Material mat)
    //{
    //    //sprite的三角形数组
    //    ushort[] triangles0 = _spriteRenderer.sprite.triangles;
    //    //mesh的三角形数组
    //    int[] meshTriangles = new int[triangles0.Length];
    //    //mesh的三角形顶点
    //    Vector3[] vertices0 = new Vector3[_spriteRenderer.sprite.vertices.Length];
    //    //存储顶点数组
    //    for (int i = 0; i < _spriteRenderer.sprite.vertices.Length; i++)
    //    {
    //        vertices0[i] = new Vector3(_spriteRenderer.sprite.vertices[i].x, _spriteRenderer.sprite.vertices[i].y, 0);
    //    }

    //    var d = _spriteRenderer.sprite.bounds;



    //    //存储三角形数组
    //    for (int i = 0; i < meshTriangles.Length; i += 3)
    //    {
    //        meshTriangles[i] = triangles0[i];
    //        meshTriangles[i + 1] = triangles0[i + 1];
    //        meshTriangles[i + 2] = triangles0[i + 2];
    //        // yield return new WaitForSeconds(0.02f);
    //        // Debug.DrawLine(vertices0[meshTriangles[i]], vertices0[meshTriangles[i + 1]], Color.red, 100.0f);
    //        //Debug.DrawLine(vertices0[meshTriangles[i + 1]], vertices0[meshTriangles[i + 2]], Color.red, 100.0f);
    //        // Debug.DrawLine(vertices0[meshTriangles[i + 2]], vertices0[meshTriangles[i]], Color.red, 100.0f);
    //    }
    //    //存储sprite的texture
    //    Texture2D texture = _spriteRenderer.sprite.texture;
    //    //生成一个新的物体挂载mesh组件
    //    //GameObject go = new GameObject();
    //    MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>();
    //    MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();
    //    Mesh _mesh = new Mesh();
    //    //meshFilter.mesh = _mesh;

    //    //给mesh赋值
    //    _mesh.vertices = vertices0;
    //    _mesh.uv = _spriteRenderer.sprite.uv;
    //    _mesh.triangles = meshTriangles;

    //    //设置物体位置,名字等
    //    // go.name = _spriteRenderer.name;

    //    var asstMesh = AssetDatabase.LoadAssetAtPath<Mesh>("Assets/LayaMesh/" + texture.name + ".mesh");
    //    if (asstMesh == null)
    //        meshFilter.mesh = SaveMeshExt(_spriteRenderer, texture.name);
    //    else
    //    {
    //        meshFilter.mesh = asstMesh;

    //    }




    //    //销毁原Sprite
    //    // DestroyImmediate(gameObject);

    //    meshRenderer.material = mat;
    //}
    static void GenerateFormSpriteExt(SpriteRenderer _spriteRenderer, GameObject gameObject, Material mat)
    {
        

        
        
        

       
        //存储sprite的texture
        Texture2D texture = _spriteRenderer.sprite.texture;
        //生成一个新的物体挂载mesh组件
        //GameObject go = new GameObject();
        MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>();
        MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>();
        Mesh _mesh = new Mesh();
        meshFilter.mesh = _mesh;

     



        var asstMesh = AssetDatabase.LoadAssetAtPath<Mesh>("Assets/LayaMesh/" + texture.name + ".mesh");
        if (asstMesh == null)
        {
            _mesh = UpdateMesh(_spriteRenderer, _mesh, meshFilter);
            meshFilter.mesh = SaveMeshExt(_mesh, texture.name);
        }
        else
        {
            meshFilter.mesh = asstMesh;

        }




        //销毁原Sprite
       // DestroyImmediate(gameObject);

        meshRenderer.material = mat;
    }

    static void CreatMatAndMesh(SpriteRenderer sp, GameObject obj)
    {
        if (sp && sp.sprite)
        {
            // Debug.Log(sp.sprite.name);
            GenerateFormSpriteExt(sp, obj, CreatMatAsset(sp.sprite.name, sp.color));


        }



    }

    [MenuItem("JieTools/SaveMesh")]
    static void SaveMesh()
    {
        var g = Selection.activeGameObject;

        var _spriteRenderer = g.GetComponent<SpriteRenderer>();
        //sprite的三角形数组
        ushort[] triangles0 = _spriteRenderer.sprite.triangles;
        //mesh的三角形数组
        int[] meshTriangles = new int[triangles0.Length];
        //mesh的三角形顶点
        Vector3[] vertices0 = new Vector3[_spriteRenderer.sprite.vertices.Length];
        //存储顶点数组
        for (int i = 0; i < _spriteRenderer.sprite.vertices.Length; i++)
        {
            vertices0[i] = new Vector3(_spriteRenderer.sprite.vertices[i].x, _spriteRenderer.sprite.vertices[i].y, 0);
        }
        //存储三角形数组
        for (int i = 0; i < meshTriangles.Length; i += 3)
        {
            meshTriangles[i] = triangles0[i];
            meshTriangles[i + 1] = triangles0[i + 1];
            meshTriangles[i + 2] = triangles0[i + 2];
            // yield return new WaitForSeconds(0.02f);
            // Debug.DrawLine(vertices0[meshTriangles[i]], vertices0[meshTriangles[i + 1]], Color.red, 100.0f);
            //Debug.DrawLine(vertices0[meshTriangles[i + 1]], vertices0[meshTriangles[i + 2]], Color.red, 100.0f);
            // Debug.DrawLine(vertices0[meshTriangles[i + 2]], vertices0[meshTriangles[i]], Color.red, 100.0f);
        }



        Mesh _mesh = new Mesh();


        //给mesh赋值
        _mesh.vertices = vertices0;
        _mesh.uv = _spriteRenderer.sprite.uv;
        _mesh.triangles = meshTriangles;
        AssetDatabase.CreateAsset(_mesh, "Assets/LayaMesh/1.mesh");


        AssetDatabase.SaveAssets();

        AssetDatabase.Refresh();


    }

    static Mesh SaveMeshExt_old(SpriteRenderer _spriteRenderer,string name)
    {
      

      
        //sprite的三角形数组
        ushort[] triangles0 = _spriteRenderer.sprite.triangles;
        //mesh的三角形数组
        int[] meshTriangles = new int[triangles0.Length];
        //mesh的三角形顶点
        Vector3[] vertices0 = new Vector3[_spriteRenderer.sprite.vertices.Length];
        //存储顶点数组
        for (int i = 0; i < _spriteRenderer.sprite.vertices.Length; i++)
        {
            vertices0[i] = new Vector3(_spriteRenderer.sprite.vertices[i].x, _spriteRenderer.sprite.vertices[i].y, 0);
        }
        //存储三角形数组
        for (int i = 0; i < meshTriangles.Length; i += 3)
        {
            meshTriangles[i] = triangles0[i];
            meshTriangles[i + 1] = triangles0[i + 1];
            meshTriangles[i + 2] = triangles0[i + 2];
            // yield return new WaitForSeconds(0.02f);
            // Debug.DrawLine(vertices0[meshTriangles[i]], vertices0[meshTriangles[i + 1]], Color.red, 100.0f);
            //Debug.DrawLine(vertices0[meshTriangles[i + 1]], vertices0[meshTriangles[i + 2]], Color.red, 100.0f);
            // Debug.DrawLine(vertices0[meshTriangles[i + 2]], vertices0[meshTriangles[i]], Color.red, 100.0f);
        }



        Mesh _mesh = new Mesh();


        //给mesh赋值
        _mesh.vertices = vertices0;
        _mesh.uv = _spriteRenderer.sprite.uv;
        _mesh.triangles = meshTriangles;
        AssetDatabase.CreateAsset(_mesh, "Assets/LayaMesh/"+ name + ".mesh");


        AssetDatabase.SaveAssets();

        AssetDatabase.Refresh();

        return _mesh;


    }


    static Mesh SaveMeshExt(Mesh _mesh, string name)
    {



    



      


        AssetDatabase.CreateAsset(_mesh, "Assets/LayaMesh/" + name + ".mesh");


        AssetDatabase.SaveAssets();

        AssetDatabase.Refresh();

        return _mesh;


    }

    public static Mesh UpdateMesh(SpriteRenderer spriteRenderer,Mesh mesh,MeshFilter _meshFilter)
    {
        //Mesh mesh = new Mesh();

        //计算Plane大小
        Vector2 size;
        // size.x = _cellSize.x * _gridSize.x;
        //  size.y = _cellSize.y * _gridSize.y;

        var orglocalScale = spriteRenderer.transform.localScale;

        var orgrotation = spriteRenderer.transform.rotation;


        spriteRenderer.transform.localScale = Vector3.one;
        spriteRenderer.transform.rotation = Quaternion.identity;
        var _cellSize = new Vector2(spriteRenderer.bounds.size.x, spriteRenderer.bounds.size.y);
       // var _cellSize = new Vector2(1,1);
        size = _cellSize;
        var _gridSize = new Vector2Int(1, 1);
        //计算Plane一半大小
        Vector2 halfSize = size / 2;

        //计算顶点及UV
        List<Vector3> vertices = new List<Vector3>();
        List<Vector2> uvs = new List<Vector2>();

        Vector3 vertice = Vector3.zero;
        Vector2 uv = Vector3.zero;

        for (int y = 0; y < _gridSize.y + 1; y++)
        {
            //vertice.z = y * _cellSize.y - halfSize.y;//计算顶点Y轴
            vertice.z = 0;
            // uv.y = y * _cellSize.y / size.y;//计算顶点纹理坐标V
            vertice.y = y * _cellSize.y - halfSize.y;

            for (int x = 0; x < _gridSize.x + 1; x++)
            {
                vertice.x = x * _cellSize.x - halfSize.x;//计算顶点X轴
                uv.x = x * _cellSize.x / size.x;//计算顶点纹理坐标U
                uv.y = y * _cellSize.y / size.y;//计算顶点纹理坐标U

                vertices.Add(vertice);//添加到顶点数组
                uvs.Add(uv);//添加到纹理坐标数组
            }
        }

        //顶点序列
        int a = 0;
        int b = 0;
        int c = 0;
        int d = 0;
        int startIndex = 0;
        int[] indexs = new int[_gridSize.x * _gridSize.y * 2 * 3];//顶点序列
        for (int y = 0; y < _gridSize.y; y++)
        {
            for (int x = 0; x < _gridSize.x; x++)
            {
                //四边形四个顶点
                a = y * (_gridSize.x + 1) + x;//0
                b = (y + 1) * (_gridSize.x + 1) + x;//1
                c = b + 1;//2
                d = a + 1;//3

                //计算在数组中的起点序号
                startIndex = y * _gridSize.x * 2 * 3 + x * 2 * 3;

                //左上三角形
                indexs[startIndex] = a;//0
                indexs[startIndex + 1] = b;//1
                indexs[startIndex + 2] = c;//2

                //右下三角形
                indexs[startIndex + 3] = c;//2
                indexs[startIndex + 4] = d;//3
                indexs[startIndex + 5] = a;//0
            }
        }

        //
        mesh.SetVertices(vertices);//设置顶点
        mesh.SetUVs(0, uvs);//设置UV
        mesh.SetIndices(indexs, MeshTopology.Triangles, 0);//设置顶点序列
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        mesh.RecalculateTangents();

        _meshFilter.mesh = mesh;

        spriteRenderer.transform.localScale = spriteRenderer.transform.localScale;
        spriteRenderer.transform.rotation = orgrotation;

        return mesh;
    }


}

解压密码:280442832_s2m

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程之力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值