unity编辑器拓展八——unity里面分离模型

时间紧 直接上图上代码

 

 

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

public class SplitMesh : EditorWindow {
    //基础模型段数
     int beseSegmentx = 0;
     int beseSegmenty = 0;
    //计划分几段
     int segmentx = 0;
     int segmenty = 0;
    [MenuItem("tool/Splitmesh")]
    static void splitMesh01()
    {
        SplitMesh win = (SplitMesh)EditorWindow.GetWindow(typeof(SplitMesh), false, "splitmesh", false);
        win.Show();
    }

    void OnGUI()
    {
        GUIStyle style1 = new GUIStyle();
        style1.fontSize = 15;
        style1.normal.textColor = new Color(0.7f, 0.7f, 0.7f);

        EditorGUILayout.LabelField("▼SplitMesh", style1);
        GUILayout.BeginHorizontal();
        {    
            EditorGUILayout.LabelField("x方向原始段数", style1,GUILayout.Width(120));
            beseSegmentx = EditorGUILayout.IntField(beseSegmentx, GUILayout.Width(30));

            EditorGUILayout.LabelField("x方向划分段数", style1, GUILayout.Width(120));
            segmentx = EditorGUILayout.IntField(segmentx, GUILayout.Width(30));
        }
        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        {
            EditorGUILayout.LabelField("y方向原始段数", style1, GUILayout.Width(120));
            beseSegmenty = EditorGUILayout.IntField(beseSegmenty, GUILayout.Width(30));

            EditorGUILayout.LabelField("y方向划分段数", style1, GUILayout.Width(120));
            segmenty = EditorGUILayout.IntField(segmenty, GUILayout.Width(30));
        }
        GUILayout.EndHorizontal();

       if (GUI.Button(new Rect(100, 60, 80, 30), "Begin"))
        {
            splitMesh();

        }
    }




    private void splitMesh()
    {
       
        //取选择模型
        Transform baseMesh = Selection.activeGameObject.transform;
        GameObject parent = new GameObject(baseMesh + "_"+"Split");
        if (baseMesh.parent != null)
        parent.transform.SetParent(baseMesh.parent);

        parent.transform.position = Vector3.zero;
        parent.transform.eulerAngles = Vector3.zero;
        parent.transform.localScale = Vector3.one;




        //起始点
        Vector2 begin = new Vector2(0, 0);

        //划分后每个大段的长度 用顶点的方式来表达
        int lenthX = beseSegmentx / segmentx;
        int lenthY = beseSegmenty / segmenty;


        //取基础模型的顶点数组
        Vector3[] baseverts = baseMesh.GetComponent<MeshFilter>().sharedMesh.vertices;
        Vector2[] uv01 = baseMesh.GetComponent<MeshFilter>().sharedMesh.uv;
        //Vector2[] uv02 = baseMesh.GetComponent<MeshFilter>().sharedMesh.uv2;
        Debug.Log(baseverts.Length + "," + uv01.Length );


        //顶点 uv
        //每段的顶点数组存在一个list数组vertes里面
        List<List<Vector3>> vertes = new List<List<Vector3>>();//顶点
        List<List<Vector2>> uv1 = new List<List<Vector2>>();//uv
        List<List<Vector2>> uv2 = new List<List<Vector2>>();//uv
        

        //每段的起始点 跟每段的结束点
        Vector2 tmpbegin = begin;
        Vector2 tmpEnd = new Vector2(tmpbegin.x + lenthX, tmpbegin.y + lenthY);
        
        //while循环次数  跟被划分的模型次数一样 所以while条件为模型的个数
        int sumcount = 0;
        while (sumcount < segmentx * segmenty)//这个条件要改 循环次数应该跟模块的数量有关系  
        {
            List<Vector3> tmp = new List<Vector3>();
            List<Vector2> tmp2 = new List<Vector2>();
            List<Vector2> tmp3 = new List<Vector2>();
            //一次循环完 会将第一段模型顶点加入数组

            for (int i = 0; i < beseSegmenty+1; i++)
            {
                for (int j = 0; j < beseSegmentx+1; j++)
                {
                   
                    if (j >= tmpbegin.x && j <= tmpEnd.x && i >= tmpbegin.y && i <= tmpEnd.y)
                    {
                        tmp.Add(baseverts[(beseSegmentx + 1) * i + j]);
                        tmp2.Add(uv01[(beseSegmentx + 1) * i + j]);
                        //tmp3.Add(uv02[(beseSegmentx + 1) * i + j]);
                    }
                }               
            }
    
            //将for循环里的顶点数组加入到list数组里面
            vertes.Add(tmp);
            uv1.Add(tmp2);
            uv2.Add(tmp3);
            //完成第一个模型的顶点数组后 开始第二个数组的准备
            sumcount++;
            //新的起始点  将开始点的x方向往后移一段
            tmpbegin.x += lenthX;
            //当起始点x方向到达模型的最后一个点时,将起始点的x归到最初的起始点,z方向起始点移动一段
            if(tmpbegin.x == beseSegmentx)
            {
                tmpbegin.x = begin.x;
                tmpbegin.y += lenthY;
            }
            //新的结束点  根据新的起始点计算出新的结束点
            tmpEnd = new Vector2(tmpbegin.x + lenthX,  tmpbegin.y + lenthY);
        }

        // 三角形索引  每块的的长宽段数顶点都是固定的 所以它的三角形索引顺序也是固定的 这里不需要做多个模型的数组  只需要做一个模型的三角形索引  给每个mesh赋值就可以了
        //索引的数组长度
        int countVertTri = (beseSegmentx / segmentx) * (beseSegmenty/ segmenty) * 6;//长宽段数相乘 然后*6  原理请看上一篇
        //索引数组
        int[] triangles = new int[countVertTri];

        int index = 0;
        for (int i = 0; i < beseSegmenty / segmenty; i++) //按照长宽的段数来遍历 也就是按照每个小正方形 两个小三角形来遍历
        {
            for (int j = 0; j < beseSegmentx / segmentx; j++)
            {
                int role = beseSegmentx / segmentx + 1; //x方向定点数
                int self = j + (i * role);
                int next = j + ((i + 1) * role);

                triangles[index] = self;
                triangles[index + 1] = next;
                triangles[index + 2] = next + 1;

                triangles[index + 3] = self;
                triangles[index + 4] = next + 1;
                triangles[index + 5] = self + 1;

                index += 6;
            }
        }

        //给mesh提取出来 渲染模型

        for (int i = 0; i < vertes.Count; i++)
        {

            Mesh mesh = new Mesh();
            mesh.name = "mesh" +"_"+ i;
            mesh.vertices = vertes[i].ToArray();
            mesh.uv = uv1[i].ToArray();
            //mesh.uv2 = uv2[i].ToArray();
            mesh.triangles = triangles;
            mesh.RecalculateNormals();
            Material m = baseMesh.GetComponent<MeshRenderer>().sharedMaterial;
            GameObject OBJ = new GameObject(baseMesh.name +"_" +i);
            OBJ.transform.SetParent(parent.transform);
            OBJ.AddComponent<MeshFilter>().sharedMesh = mesh;
            OBJ.AddComponent<MeshRenderer>().sharedMaterial = m;
        }
        parent.transform.position = baseMesh.position;
        parent.transform.eulerAngles = baseMesh.eulerAngles;
        parent.transform.localScale = baseMesh.localScale;

    }
    
}

 

亲,如果您觉得本文不错,愿意给我一些动力的话,请用手机扫描二维码即可向我打赏

                                         打赏

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值