时间紧 直接上图上代码
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;
}
}
亲,如果您觉得本文不错,愿意给我一些动力的话,请用手机扫描二维码即可向我打赏
打赏