Unity网格编程编写出自己想要的形状—(单面墙多门窗)和完整的墙
1.最终的效果如下 这是单面墙的效果
2.这是位置图
3.这是完整点位图如下图
4.下面是生成单面墙的通用代码

using System.Collections; using System.Collections.Generic; using UnityEngine; public class CeShiXieQiang : MonoBehaviour { //最好是个双面材质 public Material material; [Header ("墙面的四个点,顺序:左上,左下,右下,右上")] //切记顺序不可错误 public Transform[] transforms; //储存窗户或者门的点位置 列如窗户:位置顺序是: 右下,左下,左上,右上 public List<Vector3> listss = new List<Vector3>(); public List<Vector3> listPos = new List<Vector3>(); public Transform[] mens; public Vector2[] uvs; public int factor;//UV缩放调整 private void Awake() { for (int i = 0; i < mens.Length; i++) { listss.Add(mens[i].position); } for (int i = 0; i < transforms.Length; i++) { listPos.Add(transforms[i].position); } } public void Start() { 生成Mesh面(listss); } /// <summary> /// 计算一条线段的向量方向加一段距离 /// </summary> /// <param name="ve3">起点位置</param> /// <param name="p1">终点</param> /// <param name="p2">起点</param> /// <param name="distance">距离</param> /// <returns></returns> public Vector3 CalculateChuangHu(Vector3 ve3,Vector3 p1, Vector3 p2,float distance) { Vector3 v1; Vector3 v2 = p1 - p2; Vector3 v3 = Vector3.Normalize(v2); v1 = ve3 + (distance * v3); return v1; } //计算线段的平行线上的点 //一个点绕另一个旋转90度得到方向向量 public Vector3 CalculatingNormal(Vector3 p1, Vector3 p2) { Vector3 v1 = p2 - p1; Vector3 v2 = Quaternion.Euler(0, -90, 0) * v1; Vector3 v3 = Vector3.Normalize(v2); return v3; } /// <summary> /// 根据新增门窗计算三角面和顶点数量 /// </summary> void GetLength(out int san, out int ding) { san = 4; ding = 6; if (listss.Count == 0) return; for (int i = 0; i < listss.Count; i++) { san += 8; ding += 18; } } void 生成Mesh面(List<Vector3> MCLists) { int nowSan = 0, nowDing = 0;//当前计算到的三角面和顶点 int san, ding;//三角面顶点总数 GetLength(out san, out ding);//计算下三角形数和顶点数 Mesh mesh = new Mesh(); MeshFilter filter = gameObject.AddComponent<MeshFilter>(); Vector3[] vertices = new Vector3[san]; int[] triangle = new int[ding]; Vector3 pos = this.transform.position; //计算顶点和顶点排序 if (listss .Count == 0)//没传门窗信息 则生成一个墙体 { vertices[nowSan++] = listPos[0]; vertices[nowSan++] = listPos[1]; vertices[nowSan++] = listPos[2]; vertices[nowSan++] = listPos[3]; triangle = new int[2 * 3] { 3, 1,0, 1, 3, 2 }; } else { //门窗数量大于1 先生成左侧两个 vertices[nowSan] = listPos[0];//0 vertices[nowSan + 1] = listPos[1];//1 vertices[nowSan + 2] = new Vector3(mens[1].transform.position.x, 0, mens[1].transform.position.z);//2 vertices[nowSan + 3] = new Vector3(mens[1].transform.position.x, 5, mens[1].transform.position.z); ;//3 triangle[nowDing++] = 3; triangle[nowDing++] = 2; triangle[nowDing++] = 1; triangle[nowDing++] = 1; triangle[nowDing++] = 0; triangle[nowDing++] = 3; nowSan = 3; for (int i = 0; i < MCLists.Count; i+=4)//再生成剩下的 循环赋值三角形和顶点信息 { vertices[nowSan + 1] = new Vector3(MCLists[i].x, 0, MCLists[i].z); //4 12 vertices[nowSan + 2] = new Vector3(MCLists[i].x, MCLists[i].y, MCLists[i].z); //5 13 vertices[nowSan + 3] = new Vector3(MCLists[i + 1].x, MCLists[i + 1].y, MCLists[i + 1].z); //6 14 vertices[nowSan + 4] = new Vector3(MCLists[i + 2].x, MCLists[i + 2].y, MCLists[i + 2].z); //7 15 vertices[nowSan + 5] = new Vector3(MCLists[i + 3].x, MCLists[i + 3].y, MCLists[i + 3].z); //8 16 vertices[nowSan + 6] = new Vector3(MCLists[i + 3].x, 5, MCLists[i + 3].z); //9 17 vertices[nowSan + 7] = new Vector3(((i+3== MCLists.Count - 1) ? listPos[3].x : MCLists[i+5].x), 5, (i + 3 == MCLists.Count - 1) ? listPos[3].z: MCLists[i+5].z); //10 18 vertices[nowSan + 8] = new Vector3(((i+3 == MCLists.Count - 1) ? listPos[2].x : MCLists[i+5].x), 0, ((i + 3 == MCLists.Count - 1) ? listPos[2].z : MCLists[i+5].z)); //11 19 Debug.Log("松开了手"); //顶点顺序排序 triangle[nowDing++] = nowSan + (i == 0 ? -1 : 0); triangle[nowDing++] = nowSan + 2; triangle[nowDing++] = nowSan + 1; triangle[nowDing++] = nowSan + (i == 0 ? -1 : 0); triangle[nowDing++] = nowSan + 3; triangle[nowDing++] = nowSan + 2; triangle[nowDing++] = nowSan + 4; triangle[nowDing++] = nowSan + 6; triangle[nowDing++] = nowSan + 5; triangle[nowDing++] = nowSan + 4; triangle[nowDing++] = nowSan + (i == 0 ? 0 : -1); triangle[nowDing++] = nowSan + 6; triangle[nowDing++] = nowSan + 1; triangle[nowDing++] = nowSan + 6; triangle[nowDing++] = nowSan + 7; triangle[nowDing++] = nowSan + 1; triangle[nowDing++] = nowSan + 7; triangle[nowDing++] = nowSan + 8; nowSan += 8; } } //UV计算 int iuv = 0, idx = 0; Vector3[] uvv = new Vector3[san]; uvs = new Vector2[san]; uvv[0] = Vector3.zero; for (int u = 1; u < san; u++) uvv[u] = vertices[idx] - vertices[idx + u]; idx += 8; uvs[iuv++] = Vector2.zero; for (int u = 1; u < san; u++) uvs[iuv++] = new Vector2(uvv[u].x, -uvv[u].y) * factor; mesh.vertices = vertices; mesh.triangles = triangle; mesh.uv = uvs; mesh.MarkDynamic(); mesh.RecalculateBounds(); mesh.RecalculateNormals(); MeshRenderer render = this.gameObject.AddComponent<MeshRenderer>(); render.material = material; filter.mesh = mesh; } }
5.脚本设置
材质球设置如下
(借鉴这篇博主的代码扩展:https://blog.csdn.net/qq_35080168/article/details/88524975)
万变不离其宗的办法
1.最后扩展成生成6个面的Mesh组成一个有厚度的墙壁记录一下,方便以后能想起来(直接用是肯定不能用的,如有需要自行扩展即可)

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class ChVector { public Vector3 chVector; public float chAngle; } /// <summary> /// 生成洞口代码 /// </summary> public class AddEntrance : MonoBehaviour { bool fishbool = false; GameObject objPlane; private Image imageObj; public Material material; private void Start() { objPlane = Instantiate(GameManager.instance_.dKCloneObj, BooLManager.GetInstance().GetModelTransform(Draw.instance_.dkParent, GameManager. instance_.intFloorUp)); objPlane.name = "洞口UI"; imageObj = objPlane.GetComponent<Image>(); objPlane.SetActive(false); } /// <summary> /// 开启画线 /// </summary> public void OpenDrawingWall() { BooLManager.GetInstance().dk_Bool = true; fishbool = true; objPlane.SetActive(true); } /// <summary> /// 克隆物体 /// </summary> public void CloneObj(Vector3 position_) { GameObject objP = Instantiate(GameManager.instance_.dKCloneObj, BooLManager.GetInstance().GetModelTransform(Draw.instance_.dkParent, GameManager. instance_.intFloorUp)); objP.transform.position = position_; objP.transform.rotation = imageObj.transform.rotation; objP.GetComponent<Image>().color = Color.green; } /// <summary> /// 关闭画线 /// </summary> public void CloseDrawingWall() { BooLManager.GetInstance().dk_Bool = false; objPlane.SetActive(false); } /// <summary> /// 图片变颜色 /// </summary> /// <param name="color"></param> public void ColorPlane(Color color ) { imageObj.color = color; } public void LineAngle(float aa) { objPlane.transform.rotation = Quaternion.Euler(new Vector3(0, 0, aa)); } private void Update() { if (fishbool) { Vector3 uuu = Input.mousePosition; objPlane.transform.position = uuu; } if (BooLManager.GetInstance().dk_Bool) { if (Input.GetMouseButtonUp(1)) { objPlane.SetActive(false); } else if (Input.GetMouseButtonUp(0)) { objPlane.SetActive(true); } } } /// <summary> /// 计算斜方向的加距离 /// </summary> /// <param name="lr">线段</param> /// <param name="ve3">门窗的点位</param> /// <returns></returns> public Vector3 CalculateChuangHu(LineRenderer lr, Vector3 ve3) { Vector3 v1 ; Vector3 v2 = lr.GetPosition(1) - lr.GetPosition(0); Vector3 v21 = ve3 - lr.GetPosition(0); float jd = Vector3.Angle(v2, v21); Vector3 v3 = Vector3.Normalize(v2); float fol1 = Vector3.Distance(lr.GetPosition(0), ve3); float fol2 = Mathf.Cos(jd) *fol1; v1 = lr.GetPosition(0) + (fol2+GameManager.cmkd)* v3; return v1; } public Vector3 CalculateChuangHu(LineRenderer lr, Vector3 ve3,float kd) { Vector3 v1; Vector3 v2 = lr.GetPosition(1) - lr.GetPosition(0); Vector3 v21 = ve3 - lr.GetPosition(0); float jd = Vector3.Angle(v2, v21); Vector3 v3 = Vector3.Normalize(v2); float fol1 = Vector3.Distance(lr.GetPosition(0), ve3); float fol2 = Mathf.Cos(jd) * fol1; v1 = lr.GetPosition(0) + (fol2 + kd) * v3; return v1; } /// <summary> /// 计算斜方向的减距离 /// </summary> /// <param name="lr"></param> /// <param name="ve3"></param> /// <returns></returns> public Vector3 CalculateChuangHu_(LineRenderer lr, Vector3 ve3) { Vector3 v1; Vector3 v2 = lr.GetPosition(1) - lr.GetPosition(0); Vector3 v21 = ve3 - lr.GetPosition(0); float jd = Vector3.Angle(v2, v21); Vector3 v3 = Vector3.Normalize(v2); float fol1 = Vector3.Distance(lr.GetPosition(0), ve3); float fol2 = Mathf.Cos(jd) * fol1; v1 = lr.GetPosition(0) + (fol2- GameManager.cmkd) * v3; return v1; } public Vector3 CalculateChuangHu_(LineRenderer lr, Vector3 ve3, float kd) { Vector3 v1; Vector3 v2 = lr.GetPosition(1) - lr.GetPosition(0); Vector3 v21 = ve3 - lr.GetPosition(0); float jd = Vector3.Angle(v2, v21); Vector3 v3 = Vector3.Normalize(v2); float fol1 = Vector3.Distance(lr.GetPosition(0), ve3); float fol2 = Mathf.Cos(jd) * fol1; v1 = lr.GetPosition(0) + (fol2 - kd) * v3; return v1; } //洞的数据 private void GetDongData(LineRenderer lrr, List<Vector3> lists) { if (lists.Count > 0) { for (int k = 0; k < lists.Count; k++) //顺时针的洞点位 { listMCs.Add(CalculateChuangHu(lrr, lists[k]) + new Vector3(0, GameManager.cmin, 0)); listMCs.Add(CalculateChuangHu_(lrr, lists[k]) + new Vector3(0, GameManager.cmin, 0)); listMCs.Add(CalculateChuangHu_(lrr, lists[k]) + new Vector3(0, GameManager.cmax, 0)); listMCs.Add(CalculateChuangHu(lrr, lists[k]) + new Vector3(0, GameManager.cmax, 0)); listMCs_.Add((CalculateChuangHu(lrr, lists[k]) + new Vector3(0, GameManager.cmin, 0)) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu_(lrr, lists[k]) + new Vector3(0, GameManager.cmin, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu_(lrr, lists[k]) + new Vector3(0, GameManager.cmax, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu(lrr, lists[k]) + new Vector3(0, GameManager.cmax, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); } } } //窗户的数据 private void GetChuangData(LineRenderer lrr, List<Vector3> listch) { if (listch.Count > 0) //窗户 { for (int k = 0; k < listch.Count; k++) { listMCs.Add(CalculateChuangHu(lrr, listch[k]) + new Vector3(0, GameManager.cmin, 0)); listMCs.Add(CalculateChuangHu_(lrr, listch[k]) + new Vector3(0, GameManager.cmin, 0)); listMCs.Add(CalculateChuangHu_(lrr, listch[k]) + new Vector3(0, GameManager.cmax, 0)); listMCs.Add(CalculateChuangHu(lrr, listch[k]) + new Vector3(0, GameManager.cmax, 0)); listMCs_.Add((CalculateChuangHu(lrr, listch[k]) + new Vector3(0, GameManager.cmin, 0)) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu_(lrr, listch[k]) + new Vector3(0, GameManager.cmin, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu_(lrr, listch[k]) + new Vector3(0, GameManager.cmax, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu(lrr, listch[k]) + new Vector3(0, GameManager.cmax, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); ChVector chVec = new ChVector(); chVec.chVector = BooLManager.GetInstance().CalculateChuangHu_(lrr, listch[k]) + new Vector3(0, GameManager.ccloneY, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * 0.1f; chVec.chAngle = BooLManager.GetInstance().CalculatingAngle_(lrr) + 90f; chListData.Add(chVec); } } } //单开门的数据 private void GetDKMenData(LineRenderer lrr, List<Vector3> listch) { if (listch.Count > 0) //单开门 { for (int k = 0; k < listch.Count; k++) { listMCs.Add(CalculateChuangHu(lrr, listch[k],GameManager.dkmkd) + new Vector3(0, GameManager.dkmmin, 0)); listMCs.Add(CalculateChuangHu_(lrr, listch[k], GameManager.dkmkd) + new Vector3(0, GameManager.dkmmin, 0)); listMCs.Add(CalculateChuangHu_(lrr, listch[k], GameManager.dkmkd) + new Vector3(0, GameManager.dkmmax, 0)); listMCs.Add(CalculateChuangHu(lrr, listch[k], GameManager.dkmkd) + new Vector3(0, GameManager.dkmmax, 0)); listMCs_.Add((CalculateChuangHu(lrr, listch[k], GameManager.dkmkd) + new Vector3(0, GameManager.dkmmin, 0)) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu_(lrr, listch[k], GameManager.dkmkd) + new Vector3(0, GameManager.dkmmin, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu_(lrr, listch[k], GameManager.dkmkd) + new Vector3(0, GameManager.dkmmax, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu(lrr, listch[k], GameManager.dkmkd) + new Vector3(0, GameManager.dkmmax, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); ChVector chVec = new ChVector(); chVec.chVector = BooLManager.GetInstance().CalculateChuangHu_(lrr, listch[k])+ new Vector3(0, GameManager.dkmY, 0)+ BooLManager.GetInstance().RotatePointAroundPivot(lrr) * 0.1f; chVec.chAngle = BooLManager.GetInstance().CalculatingAngle_(lrr) + 90f; dkmListData.Add(chVec); } } } //双开门的数据 private void GetSKMenData(LineRenderer lrr, List<Vector3> listch) { if (listch.Count > 0) //双开门 { for (int k = 0; k < listch.Count; k++) { listMCs.Add(CalculateChuangHu(lrr, listch[k], GameManager.skmkd) + new Vector3(0, GameManager.skmmin, 0)); listMCs.Add(CalculateChuangHu_(lrr, listch[k], GameManager.skmkd) + new Vector3(0, GameManager.skmmin, 0)); listMCs.Add(CalculateChuangHu_(lrr, listch[k], GameManager.skmkd) + new Vector3(0, GameManager.skmmax, 0)); listMCs.Add(CalculateChuangHu(lrr, listch[k], GameManager.skmkd) + new Vector3(0, GameManager.skmmax, 0)); listMCs_.Add((CalculateChuangHu(lrr, listch[k], GameManager.skmkd) + new Vector3(0, GameManager.skmmin, 0)) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu_(lrr, listch[k], GameManager.skmkd) + new Vector3(0, GameManager.skmmin, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu_(lrr, listch[k], GameManager.skmkd) + new Vector3(0, GameManager.skmmax, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); listMCs_.Add(CalculateChuangHu(lrr, listch[k], GameManager.skmkd) + new Vector3(0, GameManager.skmmax, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick); ChVector chVec = new ChVector(); chVec.chVector = BooLManager.GetInstance().CalculateChuangHu_(lrr, listch[k]) + new Vector3(0, GameManager.dkmY, 0) + BooLManager.GetInstance().RotatePointAroundPivot(lrr) * 0.1f; chVec.chAngle = BooLManager.GetInstance().CalculatingAngle_(lrr) + 90f; skmListData.Add(chVec); } } } /// <summary> /// 获取所有数据 /// </summary> /// <param name="lrr">线</param> /// <param name="lists">洞口的数据</param> /// <param name="listch">窗户的数据</param> /// <param name="listdkm">单开门的数据</param> /// <param name="listskm">双开门的数据</param> public void GetALLData(LineRenderer lrr, List <Vector3> lists,List <Vector3>listch,List<Vector3>listdkm, List<Vector3> listskm) { AllClearList(); GetDongData(lrr, lists); GetChuangData(lrr, listch); GetDKMenData(lrr, listdkm); GetSKMenData(lrr, listskm); GetCeMianDianData(lrr); GetDiMian(); } List<Vector3> listLines = new List<Vector3>();//内侧面的点 List<Vector3> listMCs = new List<Vector3>(); //门窗的字典 List<Vector3> listLines_ = new List<Vector3>(); //外侧面 另一侧点的列表 List<Vector3> listMCs_ = new List<Vector3>(); //另一侧门窗的列表 List<Vector3> listLines_Dimian = new List<Vector3>(); //底面的列表 List<Vector3> listLines_Dingmian = new List<Vector3>(); //顶面的列表 List<Vector3> listLines_leftMian = new List<Vector3>(); //左面的列表 List<Vector3> listLines_RightMian = new List<Vector3>(); //右面的列表 List<ChVector> chListData = new List<ChVector>(); //生成窗户的位置和角度 List<ChVector> dkmListData = new List<ChVector>(); //生成的单开门的位置和角度 List<ChVector> skmListData = new List<ChVector>(); //生成双开门的位置和角度 /// <summary> /// 获取侧面的数据 /// </summary> /// <param name="lrr"></param> private void GetCeMianDianData(LineRenderer lrr) { listLines.Add(new Vector3(lrr.GetPosition(0).x, GameManager.qmax, lrr.GetPosition(0).z)); listLines.Add(new Vector3(lrr.GetPosition(0).x, GameManager.qmin, lrr.GetPosition(0).z)); listLines.Add(new Vector3(lrr.GetPosition(1).x, GameManager.qmin, lrr.GetPosition(1).z)); listLines.Add(new Vector3(lrr.GetPosition(1).x, GameManager.qmax, lrr.GetPosition(1).z)); listLines_.Add(BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick + lrr.GetPosition(0) + new Vector3(0, GameManager.qmax, 0)); listLines_.Add(BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick + lrr.GetPosition(0) + new Vector3(0, GameManager.qmin, 0)); listLines_.Add(BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick + lrr.GetPosition(1) + new Vector3(0, GameManager.qmin, 0)); listLines_.Add(BooLManager.GetInstance().RotatePointAroundPivot(lrr) * GameManager.qthick + lrr.GetPosition(1) + new Vector3(0, GameManager.qmax, 0)); } //获取面的数据 private void GetDiMian() { //底面 listLines_Dimian.Add(listLines_[1]); listLines_Dimian.Add(listLines[1]); listLines_Dimian.Add(listLines_[2]); listLines_Dimian.Add(listLines[2]); //顶面 listLines_Dingmian.Add(listLines_[0]); listLines_Dingmian.Add(listLines[0]); listLines_Dingmian.Add(listLines_[3]); listLines_Dingmian.Add(listLines[3]); //左侧面 listLines_leftMian.Add(listLines_[0]); listLines_leftMian.Add(listLines_[1]); listLines_leftMian.Add(listLines[0]); listLines_leftMian.Add(listLines[1]); //右侧面 listLines_RightMian.Add(listLines_[3]); listLines_RightMian.Add(listLines_[2]); listLines_RightMian.Add(listLines[3]); listLines_RightMian.Add(listLines[2]); } /// <summary> /// 生成其他面的方法 /// </summary> private void HeBingDataWall() { CreateThreeD(listLines_Dimian); CreateThreeD(listLines_Dingmian); CreateThreeD(listLines_leftMian); CreateThreeD(listLines_RightMian); } /// <summary> /// 清空数据 /// </summary> private void AllClearList() { listMCs.Clear(); listMCs_.Clear(); listLines.Clear(); listLines_.Clear(); listLines_Dimian.Clear(); listLines_Dingmian.Clear(); listLines_leftMian.Clear(); listLines_RightMian.Clear(); chListData.Clear(); dkmListData.Clear(); skmListData.Clear(); } /// <summary> /// 获取全部数据 生成全部墙面 /// </summary> public void HuoQuQuanBuData() { Transform lines = BooLManager.GetInstance().GetModelTransform (Draw.instance_.lineMeshParent, GameManager.instance_.intFloorUp); for (int i = 0; i < lines.childCount; i++) { LineRenderer lr = lines.GetChild(i).GetComponent<LineRenderer>(); AddPointBit ap = lines.GetChild(i).GetComponent<AddPointBit>(); GetALLData(lr, ap.listDong,ap.listChuang,ap.listDkm,ap.listSkm); Debug.Log("这是几次循环"); CloneMenChuangWall(); CloneMenChuangWall_(); HeBingDataWall(); } } /// <summary> /// 根据新增门窗计算三角面和顶点数量 /// </summary> void GetLength(out int san, out int ding) { san = 4; ding = 6; if (listMCs.Count == 0) return; for (int i = 0; i < listMCs.Count; i+=4) { san += 8; ding += 18; } } public Vector2[] uvs; public int factor;//UV缩放调整 private Vector3 xielvVe3; /// <summary> /// 生成侧面1 /// </summary> void CloneMenChuangWall() { int nowSan = 0, nowDing = 0;//当前计算到的三角面和顶点 int san, ding;//三角面顶点总数 GetLength(out san, out ding);//计算下三角形数和顶点数 GameObject wall = Resources.Load<GameObject>("Model/Wall"); GameObject ch = Resources.Load<GameObject>("Model/chuang"); GameObject dkm = Resources.Load<GameObject>("Model/dkm"); GameObject skm = Resources.Load<GameObject>("Model/skm"); Mesh mesh = new Mesh(); GameObject wallObj = GameObject.Instantiate(wall, BooLManager.GetInstance().GetModelTransform (Draw.instance_.models, GameManager.instance_.intFloorUp)); MeshFilter filter = wallObj.GetComponent<MeshFilter>(); Vector3[] vertices = new Vector3[san]; int[] triangle = new int[ding]; //计算顶点和顶点排序 if (listMCs.Count == 0)//没传门窗信息 则生成一个墙体 { vertices[nowSan++] = listLines[0]; vertices[nowSan++] = listLines[1]; vertices[nowSan++] = listLines[2]; vertices[nowSan++] = listLines[3]; triangle = new int[2 * 3] { 3, 1, 0, 1, 3, 2 }; } else { //门窗数量大于1 先生成左侧两个 vertices[nowSan] = listLines[0];//0 vertices[nowSan + 1] = listLines[1];//1 vertices[nowSan + 2] = new Vector3(listMCs[1].x, GameManager.qmin, listMCs[1].z);//2 vertices[nowSan + 3] = new Vector3(listMCs[1].x, GameManager.qmax, listMCs[1].z); ;//3 triangle[nowDing++] = 3; triangle[nowDing++] = 2; triangle[nowDing++] = 1; triangle[nowDing++] = 1; triangle[nowDing++] = 0; triangle[nowDing++] = 3; nowSan = 3; for (int i = 0; i < listMCs.Count; i += 4)//再生成剩下的 循环赋值三角形和顶点信息 { vertices[nowSan + 1] = new Vector3(listMCs[i].x, GameManager.qmin, listMCs[i].z); //4 12 vertices[nowSan + 2] = new Vector3(listMCs[i].x, listMCs[i].y, listMCs[i].z); //5 13 vertices[nowSan + 3] = new Vector3(listMCs[i + 1].x, listMCs[i + 1].y, listMCs[i + 1].z); //6 14 vertices[nowSan + 4] = new Vector3(listMCs[i + 2].x, listMCs[i + 2].y, listMCs[i + 2].z); //7 15 vertices[nowSan + 5] = new Vector3(listMCs[i + 3].x, listMCs[i + 3].y, listMCs[i + 3].z); //8 16 vertices[nowSan + 6] = new Vector3(listMCs[i + 3].x, GameManager.qmax, listMCs[i + 3].z); //9 17 vertices[nowSan + 7] = new Vector3(((i + 3 == listMCs.Count - 1) ? listLines[3].x : listMCs[i + 5].x), GameManager.qmax, (i + 3 == listMCs.Count - 1) ? listLines[3].z : listMCs[i + 5].z); //10 18 vertices[nowSan + 8] = new Vector3(((i + 3 == listMCs.Count - 1) ? listLines[2].x : listMCs[i + 5].x), GameManager.qmin, ((i + 3 == listMCs.Count - 1) ? listLines[2].z : listMCs[i + 5].z)); //11 19 //顶点顺序排序 triangle[nowDing++] = nowSan + (i == 0 ? -1 : 0); triangle[nowDing++] = nowSan + 2; triangle[nowDing++] = nowSan + 1; triangle[nowDing++] = nowSan + (i == 0 ? -1 : 0); triangle[nowDing++] = nowSan + 3; triangle[nowDing++] = nowSan + 2; triangle[nowDing++] = nowSan + 4; triangle[nowDing++] = nowSan + 6; triangle[nowDing++] = nowSan + 5; triangle[nowDing++] = nowSan + 4; triangle[nowDing++] = nowSan + (i == 0 ? 0 : -1); triangle[nowDing++] = nowSan + 6; triangle[nowDing++] = nowSan + 1; triangle[nowDing++] = nowSan + 6; triangle[nowDing++] = nowSan + 7; triangle[nowDing++] = nowSan + 1; triangle[nowDing++] = nowSan + 7; triangle[nowDing++] = nowSan + 8; nowSan += 8; } } CloneCHOrDKMOrSKM(ch,chListData); CloneCHOrDKMOrSKM(dkm,dkmListData); CloneCHOrDKMOrSKM(skm, skmListData); //UV计算 int iuv = 0, idx = 0; Vector3[] uvv = new Vector3[san]; uvs = new Vector2[san]; uvv[0] = Vector3.zero; for (int u = 1; u < san; u++) uvv[u] = vertices[idx] - vertices[idx + u]; idx += 8; uvs[iuv++] = Vector2.zero; for (int u = 1; u < san; u++) uvs[iuv++] = new Vector2(uvv[u].x, -uvv[u].y) * factor; mesh.vertices = vertices; mesh.triangles = triangle; mesh.uv = uvs; mesh.MarkDynamic(); mesh.RecalculateBounds(); mesh.RecalculateNormals(); wallObj.GetComponent<MeshRenderer>().material = material; ; filter.mesh = mesh; } /// <summary> /// 生成侧面2 /// </summary> void CloneMenChuangWall_() { int nowSan = 0, nowDing = 0;//当前计算到的三角面和顶点 int san, ding;//三角面顶点总数 GetLength(out san, out ding);//计算下三角形数和顶点数 GameObject wall = Resources.Load<GameObject>("Model/Wall"); Mesh mesh = new Mesh(); GameObject wallObj = GameObject.Instantiate(wall, BooLManager.GetInstance().GetModelTransform (Draw.instance_.models, GameManager.instance_.intFloorUp)); MeshFilter filter = wallObj.GetComponent<MeshFilter>(); Vector3[] vertices = new Vector3[san]; int[] triangle = new int[ding]; Vector3 pos = this.transform.position; //计算顶点和顶点排序 if (listMCs_.Count == 0)//没传门窗信息 则生成一个墙体 { vertices[nowSan++] = listLines_[0]; vertices[nowSan++] = listLines_[1]; vertices[nowSan++] = listLines_[2]; vertices[nowSan++] = listLines_[3]; triangle = new int[2 * 3] { 3, 1, 0, 1, 3, 2 }; } else { //门窗数量大于1 先生成左侧两个 vertices[nowSan] = listLines_[0];//0 vertices[nowSan + 1] = listLines_[1];//1 vertices[nowSan + 2] = new Vector3(listMCs_[1].x, GameManager.qmin, listMCs_[1].z);//2 vertices[nowSan + 3] = new Vector3(listMCs_[1].x, GameManager.qmax, listMCs_[1].z); ;//3 triangle[nowDing++] = 3; triangle[nowDing++] = 2; triangle[nowDing++] = 1; triangle[nowDing++] = 1; triangle[nowDing++] = 0; triangle[nowDing++] = 3; nowSan = 3; for (int i = 0; i < listMCs_.Count; i += 4)//再生成剩下的 循环赋值三角形和顶点信息 { vertices[nowSan + 1] = new Vector3(listMCs_[i].x, GameManager.qmin, listMCs_[i].z); //4 12 vertices[nowSan + 2] = new Vector3(listMCs_[i].x, listMCs_[i].y, listMCs_[i].z); //5 13 vertices[nowSan + 3] = new Vector3(listMCs_[i + 1].x, listMCs_[i + 1].y, listMCs_[i + 1].z); //6 14 vertices[nowSan + 4] = new Vector3(listMCs_[i + 2].x, listMCs_[i + 2].y, listMCs_[i + 2].z); //7 15 vertices[nowSan + 5] = new Vector3(listMCs_[i + 3].x, listMCs_[i + 3].y, listMCs_[i + 3].z); //8 16 vertices[nowSan + 6] = new Vector3(listMCs_[i + 3].x, GameManager.qmax, listMCs_[i + 3].z); //9 17 vertices[nowSan + 7] = new Vector3(((i + 3 == listMCs_.Count - 1) ? listLines_[3].x : listMCs_[i + 5].x), GameManager.qmax, (i + 3 == listMCs_.Count - 1) ? listLines_[3].z : listMCs_[i + 5].z); //10 18 vertices[nowSan + 8] = new Vector3(((i + 3 == listMCs_.Count - 1) ? listLines_[2].x : listMCs_[i + 5].x), GameManager.qmin, ((i + 3 == listMCs_.Count - 1) ? listLines_[2].z : listMCs_[i + 5].z)); //11 19 // //顶点顺序排序 triangle[nowDing++] = nowSan + (i == 0 ? -1 : 0); triangle[nowDing++] = nowSan + 2; triangle[nowDing++] = nowSan + 1; triangle[nowDing++] = nowSan + (i == 0 ? -1 : 0); triangle[nowDing++] = nowSan + 3; triangle[nowDing++] = nowSan + 2; triangle[nowDing++] = nowSan + 4; triangle[nowDing++] = nowSan + 6; triangle[nowDing++] = nowSan + 5; triangle[nowDing++] = nowSan + 4; triangle[nowDing++] = nowSan + (i == 0 ? 0 : -1); triangle[nowDing++] = nowSan + 6; triangle[nowDing++] = nowSan + 1; triangle[nowDing++] = nowSan + 6; triangle[nowDing++] = nowSan + 7; triangle[nowDing++] = nowSan + 1; triangle[nowDing++] = nowSan + 7; triangle[nowDing++] = nowSan + 8; nowSan += 8; } } //UV计算 int iuv = 0, idx = 0; Vector3[] uvv = new Vector3[san]; uvs = new Vector2[san]; uvv[0] = Vector3.zero; for (int u = 1; u < san; u++) uvv[u] = vertices[idx] - vertices[idx + u]; idx += 8; uvs[iuv++] = Vector2.zero; for (int u = 1; u < san; u++) uvs[iuv++] = new Vector2(uvv[u].x, -uvv[u].y) * factor; mesh.vertices = vertices; mesh.triangles = triangle; mesh.uv = uvs; mesh.MarkDynamic(); mesh.RecalculateBounds(); mesh.RecalculateNormals(); MeshRenderer render = wallObj.GetComponent<MeshRenderer>(); render.material = material; filter.mesh = mesh; } /// <summary> /// 生成底面 左侧面 右侧面 /// </summary> /// <param name="lists"></param> public void CreateThreeD(List<Vector3> lists) { int iVertexCount = lists.Count; int iTrsCount = lists.Count - 2; GameObject wall = Resources.Load<GameObject>("Model/Wall"); int[] newTriangles = new int[3 * iTrsCount]; for (int i = 0; i < iTrsCount; i++) { newTriangles[3 * i] = i;//固定第一个点 if (i % 2 == 0) { newTriangles[3 * i + 1] = i + 1; newTriangles[3 * i + 2] = i + 2; } else { newTriangles[3 * i + 1] = i + 2; newTriangles[3 * i + 2] = i + 1; } } Vector3[] newVertices = new Vector3[iVertexCount]; for (int i = 0; i < iVertexCount; i++) { newVertices[i] = lists[i]; } GameObject obj = GameObject.Instantiate(wall, BooLManager.GetInstance().GetModelTransform (Draw.instance_.models, GameManager.instance_.intFloorUp)); MeshFilter filter = obj.GetComponent<MeshFilter>(); Mesh msh = new Mesh(); msh.vertices = newVertices; msh.triangles = newTriangles; //重新计算法线,代码生成的mesh必须有这一步否则,阴影效果不正常 msh.RecalculateNormals(); obj.GetComponent<MeshRenderer>().material = material; filter.mesh = msh; } /// <summary> /// 生成窗户 单开门 或者双开门 /// </summary> private void CloneCHOrDKMOrSKM(GameObject obj,List <ChVector>listdata) { if (listdata.Count == 0) return; if (listdata.Count > 0) { for (int i = 0; i < listdata.Count; i++) { GameObject chObj = GameObject.Instantiate(obj, BooLManager.GetInstance().GetModelTransform (Draw.instance_.models, GameManager.instance_.intFloorUp)); chObj.transform.position = listdata[i].chVector; chObj.transform.rotation = Quaternion.Euler(0, listdata[i].chAngle, 0); } } } }

using System.Collections; using System.Collections.Generic; using UnityEngine; public class BooLManager : BaseManager<BooLManager> { /// <summary> /// 直墙bool值 /// </summary> public bool zq_Bool; /// <summary> /// 矩形墙bool /// </summary> public bool jxq_Bool; /// <summary> /// 柱子bool /// </summary> public bool zz_Bool; /// <summary> /// 弧墙bool /// </summary> public bool hq_Bool; /// <summary> /// 梁体bool /// </summary> public bool lt_Bool; /// <summary> /// 洞口bool值 /// </summary> public bool dk_Bool; /// <summary> /// 窗户bool值 /// </summary> public bool ch_Bool; /// <summary> /// 单开门bool值 /// </summary> public bool dkm_Bool; /// <summary> /// 双开门Bool值 /// </summary> public bool skm_Bool; /// <summary> /// 获取模型的子物体 /// </summary> /// <returns></returns> public Transform GetModelTransform(Transform _parent,int aa) { Transform tran_ = null; tran_ = _parent.GetChild(aa); return tran_; } /// <summary> /// 生成新的列表数据 /// </summary> /// <param name="list1">点位1列表</param> /// <param name="list2">点位2列表</param> /// <returns></returns> public List<Vector3> SetFaceting(List <Vector3>list1,List<Vector3 >list2) { List<Vector3> lists = new List<Vector3>(); int num = list1.Count + list2.Count; for (int i = 0; i < list1.Count; i++) { lists.Add (list1[i]); lists.Add(list2[i]); } return lists; } /// <summary> /// 生成line的碰撞盒 /// </summary> /// <param name="line"></param> public void AddColler(LineRenderer line) { Camera cam = GameManager.instance_.camera2D; LineRenderer lineRenderer = line.GetComponent<LineRenderer>(); Mesh lineMesh = new Mesh(); lineRenderer.BakeMesh(lineMesh, cam, true); line.gameObject.AddComponent<MeshCollider>(); line.GetComponent<MeshCollider>().sharedMesh = lineMesh; } /// <summary> /// 计算线段的旋转角度 2Dui /// </summary> /// <param name="lrr">线</param> /// <returns></returns> public float CalculatingAngle(LineRenderer lrr) { Vector3 v1 = lrr.GetPosition(1) - lrr.GetPosition(0); float aa=0; if (v1 .x <0&&v1.z >0||v1.x >0&&v1.z >0) { aa = Vector3.Angle(v1, new Vector3(1, 0, 0)); } else { aa = Vector3.Angle(v1, new Vector3(-1, 0, 0)); } return aa; } /// <summary> /// 计算门 窗的旋转角度 3D物体 /// </summary> /// <param name="lrr">line线</param> /// <returns></returns> public float CalculatingAngle_(LineRenderer lrr) { Vector3 v1 = lrr.GetPosition(1) - lrr.GetPosition(0); float aa = 0; if (v1.x < 0 && v1.z > 0 || v1.x > 0 && v1.z > 0) { aa = Vector3.Angle(v1, new Vector3(-1, 0, 0)); } else { aa = Vector3.Angle(v1, new Vector3(1, 0, 0)); } //Debug.Log("角度:" + aa); return aa; } /// <summary> /// /// 一个点绕另一个点旋转得到的垂线向量 /// </summary> /// <param name="lrr">线段</param> /// <returns></returns> public Vector3 RotatePointAroundPivot(LineRenderer lrr) { Vector3 v1 = lrr.GetPosition(1) - lrr.GetPosition(0); Vector3 v2 = Quaternion.Euler(0, -90, 0) * v1; Vector3 v3 =Vector3.Normalize (v2); return v3; } /// <summary> /// 计算生成的窗户在这条线上位置 /// </summary> /// <param name="lr"></param> /// <param name="ve3"></param> /// <returns></returns> public Vector3 CalculateChuangHu_(LineRenderer lr, Vector3 ve3) { Vector3 v1; Vector3 v2 = lr.GetPosition(1) - lr.GetPosition(0); Vector3 v21 = ve3 - lr.GetPosition(0); float jd = Vector3.Angle(v2, v21); Vector3 v3 = Vector3.Normalize(v2); float fol1 = Vector3.Distance(lr.GetPosition(0), ve3); float fol2 = Mathf.Cos(jd) * fol1; v1 = lr.GetPosition(0) + (fol2) * v3; return v1; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!