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;
    }
}
一部分计算位置的代码

 

posted @ 2023-03-20 17:05  剑起苍穹  阅读(281)  评论(3编辑  收藏  举报
/*鼠标点击特效*/