C#常用的方法

csharp

浏览数:208

2019-1-7


常用的工具类

/// <summary>
    /// 求两条线段的交点
    /// </summary>
    /// <param name="a">线段1起点a</param>
    /// <param name="b">线段1终点b</param>
    /// <param name="c">线段2起点c</param>
    /// <param name="d">线段2终点d</param>
    /// <param name="intersectionPoint">交叉点</param>
    /// <returns>是否相交</returns>
    public static bool SegmentsIntr(Vector2 a, Vector2 b, Vector2 c, Vector2 d, out Vector2 intersectionPoint)
    {
        intersectionPoint = Vector2.zero;
        // 三角形abc 面积的2倍  
        var area_abc = (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x);

        // 三角形abd 面积的2倍  
        var area_abd = (a.x - d.x) * (b.y - d.y) - (a.y - d.y) * (b.x - d.x);

        // 面积符号相同则两点在线段同侧,不相交 (对点在线段上的情况,本例当作不相交处理);  
        if (area_abc * area_abd >= 0)
        {
            return false;
        }

        // 三角形cda 面积的2倍  
        var area_cda = (c.x - a.x) * (d.y - a.y) - (c.y - a.y) * (d.x - a.x);
        // 三角形cdb 面积的2倍  
        // 注意: 这里有一个小优化.不需要再用公式计算面积,而是通过已知的三个面积加减得出.  
        var area_cdb = area_cda + area_abc - area_abd;
        if (area_cda * area_cdb >= 0)
        {
            return false;
        }

        //计算交点坐标  
        var t = area_cda / (area_abd - area_abc);
        float dx = t * (b.x - a.x);
        float dy = t * (b.y - a.y);
        intersectionPoint = new Vector2(a.x + dx, a.y + dy);
        return true;
    }

    /// <summary>
    /// 获取多边形中的点
    /// </summary>
    /// <param name="polyGon">多边形</param>
    /// <param name="gapX">横向间隔</param>
    /// <param name="gapY">纵向间隔</param>
    /// <returns></returns>
    public static List<Vector2> GetInPolygonPoints(List<Vector2> polyGon, float gapX, float gapY)
    {
        List<Vector2> resultList = new List<Vector2>();
        Vector2[] arrV2 = GetPolygonMinAndMaxPoint(polyGon);
        Vector2 minV2 = arrV2[0];
        Vector2 maxV2 = arrV2[1];

        int numX = (int)((maxV2.x - minV2.x) / gapX);
        int numY = (int)((maxV2.y - minV2.y) / gapY);
        for (int i = 0; i <= numX; i++)
        {
            if (i == 0)
                continue;

            for (int j = 0; j <= numY; j++)
            {
                if (j == 0)
                    continue;

                Vector2 v = new Vector3(minV2.x + gapX * i, minV2.y + gapY * j);
                if (MapCommon.pointInPolygon(v, polyGon))
                {
                    resultList.Add(v);
                }
            }
        }
        return resultList;
    }
    /// <summary>
    /// 随机获取多边形内的点
    /// </summary>
    /// <param name="polyGon">多边形</param>
    /// <param name="totalNum">最多的个数</param>
    /// <param name="maxTime">最大的次数</param>
    /// <returns></returns>
    public static List<Vector2> GetInPolygonRandomPoints(List<Vector2> polyGon, int totalNum, int maxTime)
    {
        List<Vector2> resultList = new List<Vector2>();
        Vector2[] arrV2 = GetPolygonMinAndMaxPoint(polyGon);
        Vector2 minV2 = arrV2[0];
        Vector2 maxV2 = arrV2[1];

        float xDis = maxV2.x - minV2.x;
        float yDis = maxV2.y - minV2.y;
        for (int i = 0; i < maxTime; i++)
        {
            float randomX = minV2.x + UnityEngine.Random.Range(0, xDis);
            float randomY = minV2.y + UnityEngine.Random.Range(0, yDis);
            Vector2 v = new Vector2(randomX, randomY);
            if (MapCommon.pointInPolygon(v, polyGon))
            {
                resultList.Add(v);
            }
            if (resultList.Count >= totalNum)
            {
                break;
            }
        }

        return resultList;
    }
    /// <summary>
    /// 获取多边形的最小坐标和最大坐标
    /// </summary>
    /// <param name="polyGon">多边形</param>
    /// <returns>索引0:最小值; 索引1:最大值;</returns>
    public static Vector2[] GetPolygonMinAndMaxPoint(List<Vector2> polyGon)
    {
        Vector2[] arrV2 = new Vector2[2];
        arrV2[0] = new Vector2(int.MaxValue, int.MaxValue);
        arrV2[1] = new Vector2(int.MinValue, int.MinValue);

        for (int i = 0; i < polyGon.Count; i++)
        {
            arrV2[0].x = Mathf.Min(arrV2[0].x, polyGon[i].x);
            arrV2[0].y = Mathf.Min(arrV2[0].y, polyGon[i].y);
            arrV2[1].x = Mathf.Max(arrV2[1].x, polyGon[i].x);
            arrV2[1].y = Mathf.Max(arrV2[1].y, polyGon[i].y);
        }
        return arrV2;
    }
    /// <summary>
    /// 两个多边形是否相交
    /// </summary>
    /// <param name="A"></param>
    /// <param name="B"></param>
    /// <returns></returns>
    public static bool PolygonIsIntersection(List<Vector2> A, List<Vector2> B)
    {
        for (int i = 0; i < A.Count - 1; i++)
        {
            for (int j = 0; j < B.Count - 1; j++)
            {
                bool b = MapCommon.CalculateIntersection(A[i], A[i + 1], B[j], B[j + 1]);
                if (b)
                {
                    return true;
                }
            }
        }
        return false;
    }
    /// <summary>
    /// A多边形是否包含B
    /// </summary>
    /// <param name="A"></param>
    /// <param name="B"></param>
    /// <returns></returns>
    public static bool PolygonAContainB(List<Vector3> A, List<Vector3> B)
    {
        List<Vector2> listA = new List<Vector2>();
        List<Vector2> listB = new List<Vector2>();

        for (int i = 0; i < A.Count; i++)
        {
            listA.Add(new Vector2(A[i].x, A[i].z));
        }
        for (int i = 0; i < B.Count; i++)
        {
            listB.Add(new Vector2(B[i].x, B[i].z));
        }

        return PolygonAContainB(listA, listB);
    }
    /// <summary>
    /// A多边形是否包含B
    /// </summary>
    /// <param name="A"></param>
    /// <param name="B"></param>
    /// <returns></returns>
    public static bool PolygonAContainB(List<Vector2> A, List<Vector2> B)
    {
        if (MapCommon.PolygonIsIntersection(A, B))//相交
        {
            return false;
        }
        for (int i = 0; i < B.Count; i++)
        {
            bool b0 = MapCommon.pointInPolygon(B[i], A);
            if (b0)
            {
                return true;
            }
        }
        return false;
    }
    /// <summary>
    /// 计算二条线段的相交点
    /// </summary>
    /// <param name="v0_start"></param>
    /// <param name="v0_end"></param>
    /// <param name="v1_start"></param>
    /// <param name="v1_end"></param>
    /// <returns></returns>
    public static bool CalculateIntersection(Vector2 v0_start, Vector2 v0_end, Vector2 v1_start, Vector2 v1_end)
    {
        Vector2 p1, p2, p3, p4;
        p1 = NormalizeBeginPoint(v0_start, v0_end);
        p2 = NormalizeEndPoint(v0_start, v0_end);
        p3 = NormalizeBeginPoint(v1_start, v1_end);
        p4 = NormalizeEndPoint(v1_start, v1_end);
        int ua_num = (int)((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x));
        int ub_num = (int)((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x));
        int denom = (int)((p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y));
        if (denom == 0)
        {
            if (ua_num == 0 && ub_num == 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        double ua = ua_num / (double)denom;
        double ub = ub_num / (double)denom;
        if (0 <= ua && ua <= 1 &&
            0 <= ub && ub <= 1)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private static Vector2 NormalizeBeginPoint(Vector2 p1, Vector2 p2)
    {
        if (p1.x < p2.x) return p1;
        if (p1.x > p2.x) return p2;
        if (p1.y < p2.y) return p1;
        if (p1.y > p2.y) return p2;
        return p1; // p1 == p2
    }
    private static Vector2 NormalizeEndPoint(Vector2 p1, Vector2 p2)
    {
        if (p1.x < p2.x) return p2;
        if (p1.x > p2.x) return p1;
        if (p1.y < p2.y) return p2;
        if (p1.y > p2.y) return p1;
        return p2; // p1 == p2
    }
    /// <summary>
    /// 检测当前点是否在多边形中
    /// </summary>
    /// <param name="vp"></param>
    /// <param name="vList"></param>
    /// <returns></returns>
    public static bool pointInPolygon(Vector2 vp, List<Vector2> vList)
    {
        int verticesCount = vList.Count;
        int nCross = 0;
        for (int i = 0; i < verticesCount; ++i)
        {
            Vector2 p0 = vList[i];
            Vector2 p1 = vList[(i + 1) % verticesCount];

            // 求解 y=p.y 与 p1 p2 的交点
            if (p0.y == p1.y)
            {   // p1p2 与 y=p0.y平行
                continue;
            }
            if (vp.y < Mathf.Min(p0.y, p1.y))
            { // 交点在p1p2延长线上
                continue;
            }
            if (vp.y >= Mathf.Max(p0.y, p1.y))
            { // 交点在p1p2延长线上
                continue;
            }
            // 求交点的 X 坐标
            float x = (float)((vp.y - p0.y) * (p1.x - p0.x)
                    / (p1.y - p0.y) + p0.x);
            if (x > vp.x)
            { // 只统计单边交点
                nCross++;
            }
        }
        // 单边交点为偶数,点在多边形之外
        return (nCross % 2 == 1);
    }

    /// <summary>
    /// 获取夹角方向
    /// </summary>
    /// <param name="vectorList"></param>
    /// <returns></returns>
    public static List<Vector3> GetDirList(List<Vector3> vectorList)
    {
        List<Vector3> dirList = new List<Vector3>();
        //首尾点相同
        if (vectorList[0].Equals(vectorList[vectorList.Count - 1]))
        {
            dirList.Add(MapCommon.GetHalfDir(vectorList[1], vectorList[0], vectorList[vectorList.Count - 2]));
            for (int i = 1; i < vectorList.Count - 1; i++)
            {
                dirList.Add(MapCommon.GetHalfDir(vectorList[i + 1], vectorList[i], vectorList[i - 1]));
            }

            dirList.Add(MapCommon.GetHalfDir(vectorList[1], vectorList[vectorList.Count - 1], vectorList[vectorList.Count - 2]));
        }
        else
        {
            dirList.Add(Vector3.Cross(Vector3.up, vectorList[0]).normalized);
            for (int i = 1; i < vectorList.Count - 2; i++)
            {
                dirList.Add(MapCommon.GetHalfDir(vectorList[i + 1], vectorList[i], vectorList[i - 1]));
            }
            dirList.Add(Vector3.Cross(Vector3.up, vectorList[vectorList.Count - 1]).normalized);
        }
        return dirList;
    }

    /// <summary>
    /// 通过 midVertexes waySize_left waySize_right 得到 leftSideVertexes和rightSideVertexes
    /// </summary>
    /// <param name="leftSideVertexes"></param>
    /// <param name="rightSideVertexes"></param>
    /// <param name="midVertexes"></param>
    /// <param name="waySize_left"></param>
    /// <param name="waySize_right"></param>
    public static void GetLeftRightSideVertexes(List<Vector3> leftSideVertexes, List<Vector3> rightSideVertexes, List<Vector3> midVertexes, float waySize_left, float waySize_right)
    {
        List<Vector3> dirList = GetDirList(midVertexes);

        for (int i = 0; i < midVertexes.Count; i++)
        {
            leftSideVertexes.Add(midVertexes[i] - waySize_left * dirList[i]);
            rightSideVertexes.Add(midVertexes[i] + waySize_right * dirList[i]);
        }
    }
    /// <summary>
    /// 获取交点
    /// </summary>
    /// <param name="intersection"></param>
    /// <param name="p0"></param>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <param name="p3"></param>
    /// <returns></returns>
    public static bool getInfiniteLineIntersection(ref Vector2 intersection, Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3)
    {
        double A1, B1, C1, A2, B2, C2;

        A1 = p1.y - p0.y;
        B1 = p0.x - p1.x;
        C1 = A1 * p0.x + B1 * p0.y;

        A2 = p3.y - p2.y;
        B2 = p2.x - p3.x;
        C2 = A2 * p2.x + B2 * p2.y;

        double delta = A1 * B2 - A2 * B1;

        if (Math.Abs(delta) < 0.01)
        {
            return false;
        }

        float x = (float)((B2 * C1 - B1 * C2) / delta);
        float y = (float)((A1 * C2 - A2 * C1) / delta);

        intersection.x = x;
        intersection.y = y;
        return true;
    }
    public static void DestoryChild(Transform parent)
    {
        int childCount = parent.childCount;
        List<GameObject> list = new List<GameObject>();
        for (int i = 0; i < childCount; i++)
        {
            list.Add(parent.GetChild(i).gameObject);
        }
        for (int i = 0; i < list.Count; i++)
        {
            GameObject.Destroy(list[i]);
        }
    }

    public static Vector3 ConvertCoordToUnity(Vector2 coordinates)
    {
        Coordinates coords = new Coordinates(coordinates.x, coordinates.y, 0);
        return coords.convertCoordinateToVector();
    }
    /// <summary>
    /// 经纬度转换为世界坐标
    /// </summary>
    /// <param name="geometry"></param>
    /// <returns></returns>
    public static List<Vector3> CoordsToVerts(IList geometry)
    {

        var convertedGeometry = new List<Vector3>();
        for (int i = 0; i < geometry.Count; i++)
        {
            if (geometry.GetType() == typeof(List<LatLng>))
            { //Mapbox 
                LatLng c = (LatLng)geometry[i];
                Coordinates coords = new Coordinates(c.Lat, c.Lng, 0);
                Vector3 p = coords.convertCoordinateToVector();
                convertedGeometry.Add(p);
            }
            else
            { //Mapzen
                IList c = (IList)geometry[i];
                Coordinates coords = new Coordinates((double)c[1], (double)c[0], 0);
                convertedGeometry.Add(coords.convertCoordinateToVector());
            }
        }
        return convertedGeometry;
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="latidute">维度</param>
    /// <param name="longitude">经度</param>
    /// <param name="alitdute">海拔高度Y</param>
    /// <returns></returns>
    public static Vector3 CoordToVert(double latidute, double longitude, double alitdute = 0)
    {
        Coordinates coords = new Coordinates(latidute, longitude, alitdute);
        return coords.convertCoordinateToVector();
    }
    /// <summary>
    /// 获取资源路径
    /// </summary>
    /// <param name="fullPath"></param>
    /// <returns></returns>
    public static string GetResourcePathForFullPath(string fullPath)
    {
        if (fullPath.IndexOf("Resources") > -1)
        {
            fullPath = fullPath.Substring(fullPath.IndexOf("Resources") + 10);
            int len = fullPath.IndexOf(".");
            if (len > -1)
            {
                fullPath = fullPath.Substring(0, len);
            }
        }
        return fullPath;
    }
    public static void ChangeShader(Material mat, string shaderName)
    {
        mat.shader = Shader.Find(shaderName);
    }
    /// <summary>
    /// 求两个向量的夹角
    /// </summary>
    /// <param name="fromVector"></param>
    /// <param name="toVector"></param>
    /// <returns></returns>
    public static float Angle(Vector3 fromVector, Vector3 toVector)
    {
        float angle = Vector3.Angle(fromVector, toVector); //求出两向量之间的夹角  
        Vector3 normal = Vector3.Cross(fromVector, toVector);//叉乘求出法线向量  
        angle *= Mathf.Sign(Vector3.Dot(normal, Vector3.up));  //求法线向量与物体上方向向量点乘,结果为1或-1,修正旋转方向  
        return angle;
    }

    public static List<int> GetIntListWithMask(int mask)
    {
        List<int> ret = new List<int>();
        for (int i = 0; i < 32; i++)
        {
            if ((mask & 1 << i) != 0)
            {
                ret.Add(i);

            }
        }
        return ret;
    }

    public static int GetMaskWithIntList(List<int> list)
    {
        int ret = 0;
        for (int i = 0; i < list.Count; i++)
        {
            ret += 1 << list[i];
        }
        return ret;
    }

    public static string GetShowStrWithMask(int mask)
    {
        string sret = "";
        for (int i = 0; i < 32; i++)
        {
            if ((mask & 1 << i) != 0)
            {
                sret += i + ",";
            }
        }
        sret = sret.TrimEnd(',');
        return sret;
    }    public static BuildingFenceStyleData Copy(this BuildingFenceStyleData self, BuildingFenceStyleData other)
    {
        self.fenceInterval = other.fenceInterval;
        self.intervalType = other.intervalType;
        self.startRelationType = other.startRelationType;
        self.startOffset = other.startOffset;
        self.count = other.count;
        self.resourcePath = other.resourcePath;
        self.edgeOffset = other.edgeOffset;
        self.itemWidth = other.itemWidth;
        self.onebyOneDis = other.onebyOneDis;
        self.heightPercent = other.heightPercent;
        self.sumLength = other.sumLength;
        self.itemScale = other.itemScale;
        return self;
    }
    /// <summary>
    /// 合并mesh
    /// </summary>
    /// <param name="meshList"></param>
    /// <returns></returns>
    public static Mesh MargeMeshList(List<Mesh> meshList)
    {
        List<Vector3> vertices = new List<Vector3>();
        List<Vector2> uv = new List<Vector2>();
        List<int> triangles = new List<int>();
        List<Vector3> normals = new List<Vector3>();

        
        for (int i = 0; i < meshList.Count; i++)
        {
            Mesh mesh = meshList[i];
            int len = vertices.Count;
            for (int j = 0; j < mesh.vertices.Length; j++)
            {
                vertices.Add(mesh.vertices[j]);
                uv.Add(mesh.uv[j]);
                normals.Add(mesh.normals[j]);
            }
            for (int j = 0; j < mesh.triangles.Length; j++)
            {
                triangles.Add(mesh.triangles[j] + len);
            }
            GameObject.Destroy(meshList[i]);
        }
        return null;
     //   meshList.Clear();
        Mesh bigMesh = new Mesh();
        bigMesh.Clear();
        bigMesh.vertices = vertices.ToArray();
        bigMesh.triangles = triangles.ToArray();
        bigMesh.uv = uv.ToArray();
        bigMesh.normals = normals.ToArray();
        return bigMesh;
    }
    /// <summary>
    /// 获取曲线上的颜色值
    /// </summary>
    /// <param name="index"></param>
    /// <param name="totalNum"></param>
    /// <param name="startColor"></param>
    /// <param name="endColor"></param>
    /// <param name="curve"></param>
    /// <returns></returns>
    public static Color GetCurveValue(int index, int totalNum, Color startColor, Color endColor, AnimationCurve curve)
    {
        float curTime = (float)(index + 1) / (float)totalNum;
        float colorTime = curve.Evaluate(curTime);
        return Color.Lerp(startColor, endColor, colorTime);
    }
    /// <summary>
    /// 获取曲线上的数值
    /// </summary>
    /// <param name="index"></param>
    /// <param name="totalNum"></param>
    /// <param name="startValue"></param>
    /// <param name="endValue"></param>
    /// <param name="curve"></param>
    /// <returns></returns>
    public static float GetCurveValue(int index, int totalNum, float startValue, float endValue, AnimationCurve curve)
    {
        float curTime = (float)(index + 1) / (float)totalNum;
        float colorTime = curve.Evaluate(curTime);
        return Mathf.Lerp(startValue, endValue, colorTime);
    }
    /// <summary>
    /// 销毁所有儿子
    /// </summary>
    /// <param name="parent"></param>
    public static void DestoryGameObjectChild(Transform parent)
    {
        int childCount = parent.transform.childCount;
        List<GameObject> list = new List<GameObject>();
        for (int i = 0; i < childCount; i++)
        {
            list.Add(parent.transform.GetChild(i).gameObject);
        }
        for (int i = 0; i < list.Count; i++)
        {
            GameObject.Destroy(list[i]);
        }
    }
    /// <summary>
    /// 获取两向量的右方向向量
    /// </summary>
    /// <param name="node"></param>
    /// <param name="node1"></param>
    /// <returns></returns>
    public static Vector3 GetRightDir(Vector3 node, Vector3 node1)
    {
        Vector3 up = new Vector3(0, 1, 0);
        Vector3 forward = node1 - node;
        forward.y = 0.0f;
        Vector3 right = Vector3.Cross(up, forward);
        right = right.normalized;
        return right;
    }
    /// <summary>
    /// 点的顺序为顺时针
    /// </summary>
    /// <param name="node1"></param>
    /// <param name="node2"></param>
    /// <param name="node3"></param>
    /// <param name="node4"></param>
    /// <returns></returns>
    public static Mesh CreateMeshBy4Node(Vector3 node1, Vector3 node2, Vector3 node3, Vector3 node4)
    {
        Vector3[] vertices = { node1, node2, node3, node4 };

        int[] triangles;

        triangles = new int[] { 1, 2, 3, 3, 0, 1 };

        Vector2[] UVcoords = new Vector2[4];
        UVcoords[0] = Vector2.Scale(Vector2.up, new Vector2(1, Vector3.Distance(node1, node4)));
        UVcoords[1] = new Vector2(0, 0);
        UVcoords[2] = new Vector2(0, 1);
        UVcoords[3] = Vector2.Scale(Vector2.one, new Vector2(1, Vector3.Distance(node2, node3)));
      
        Mesh mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.uv = UVcoords;
        mesh.triangles = triangles;
        mesh.RecalculateNormals();
        
        return mesh;
    }
    
    /// <summary>
    /// 点的顺序为顺时针
    /// </summary>
    /// <param name="node1"></param>
    /// <param name="node2"></param>
    /// <param name="node3"></param>
    /// <param name="node4"></param>
    /// <returns></returns>
    public static Mesh CreateMeshBy4NodeRoadOutline(Vector3 node1, Vector3 node2, Vector3 node3, Vector3 node4)
    {
        Vector3[] vertices = { node1, node2, node3, node4 };

        int[] triangles;

        triangles = new int[] { 1, 2, 3, 3, 0, 1 };

        Vector2[] UVcoords = new Vector2[4];
        UVcoords[0] = Vector2.zero;
        UVcoords[1] = Vector2.Scale(Vector2.right, new Vector2(Vector3.Distance(node1, node2)/10,1));//new Vector2(1*4,0);
        UVcoords[2] = Vector2.Scale(Vector2.one, new Vector2( Vector3.Distance(node3, node4)/10,1)); // new Vector2(1 * 4, 1);
        UVcoords[3] = Vector2.up;

        Mesh mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.uv = UVcoords;
        mesh.triangles = triangles;
        mesh.RecalculateNormals();
        return mesh;
    }

    /// <summary>
    /// 获取向量夹角一半的方向
    /// </summary>
    /// <param name="nextP"></param>
    /// <param name="p"></param>
    /// <param name="preP"></param>
    /// <returns></returns>
    public static Vector3 GetHalfDir(Vector3 nextP, Vector3 p, Vector3 preP)
    {
        Vector3 dir = (nextP - p).normalized;
        Vector3 dirBefore = (p - preP).normalized;
        Vector3 tangent = Vector3.Cross(Vector3.up, (dirBefore + dir) * 0.5f).normalized;
        return tangent;
    }

    /// <summary>
    /// 点的顺序为顺时针
    /// </summary>
    /// <param name="node1"></param>
    /// <param name="node2"></param>
    /// <param name="node3"></param>
    /// <param name="node4"></param>
    /// <param name="thickness">厚度</param>
    /// <returns></returns>
    public static Mesh CreateCubeMeshBy4Node(Vector3 node1, Vector3 node2, Vector3 node3, Vector3 node4, float thickness)
    {
        List<Mesh> meshList = new List<Mesh>();
        Vector3 normal1 = Vector3.Cross((node4 - node1), (node2 - node1)).normalized;
        Vector3 normal2 = Vector3.Cross((node1 - node2), (node3 - node2)).normalized;
        Vector3 normal3 = Vector3.Cross((node2 - node3), (node4 - node3)).normalized;
        Vector3 normal4 = Vector3.Cross((node3 - node4), (node1 - node4)).normalized;

        Vector3 node5 = node1 + normal1 * thickness;
        Vector3 node6 = node2 + normal1 * thickness;
        Vector3 node7 = node3 + normal1 * thickness;
        Vector3 node8 = node4 + normal1 * thickness;
        meshList.Add(MapCommon.CreateMeshBy4Node(node1, node2, node3, node4));//前面
        meshList.Add(MapCommon.CreateMeshBy4Node(node8, node7, node6, node5));//后面
        meshList.Add(MapCommon.CreateMeshBy4Node(node2, node6, node7, node3));//左面
        meshList.Add(MapCommon.CreateMeshBy4Node(node5, node1, node4, node8));//右面
        meshList.Add(MapCommon.CreateMeshBy4Node(node4, node3, node7, node8));//上面
        meshList.Add(MapCommon.CreateMeshBy4Node(node5, node6, node2, node1));//下面
        return MapCommon.MargeMeshList(meshList);
    }

    /// <summary>
    /// 返回序列点的总距离
    /// </summary>
    /// <param name="vList"></param>
    /// <returns></returns>
    public static float GetTotalDis(List<Vector3> vList)
    {
        float totalDis = 0;
        for (int i = 0; i < vList.Count - 1; i++)
        {
            totalDis += Vector3.Distance(vList[i], vList[i + 1]);
        }
        return totalDis;
    }    //多线程
    receiveThread = new Thread(new ThreadStart(_onReceiveSocket));
    receiveThread.IsBackground = true;
    receiveThread.Start();

    /// <summary>
    /// 获取物体在地面位置
    /// </summary>
    /// <param name="groundY">地面水平面高度</param>
    /// <returns>Vector3</returns>
    public static Vector3 GetWorldPosition(float groundY)
    {
        Vector3 pos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane);
        Vector3 nearClipPlanePos = Camera.main.ScreenToWorldPoint(pos);
        Vector3 dir = nearClipPlanePos - Camera.main.transform.position;
        float angle = Vector3.Angle(Vector3.down, dir);
        float dis = Mathf.Abs(Camera.main.transform.position.y - groundY) / Mathf.Cos(angle * Mathf.Deg2Rad);
        Vector3 res = dir.normalized * dis + Camera.main.transform.position;
        res.y = groundY;
        return res;
    }
    //获取系统当前时间 单位:秒
    TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();

public static int GetIntByColor(Color color)
    {
        int R = (int)(color.r * 255);
        int G = (int)(color.g * 255);
        int B = (int)(color.b * 255);
        int A = (int)(color.a * 255);
        return A << 24 | R << 16 | G << 8 | B;
    }
    public static Color GetColorByInt(int color)
    {
        float B = (float)(color & 255) / 255f;
        float G = (float)(color >> 8 & 255) / 255f;
        float R = (float)(color >> 16 & 255) / 255f;
        float A = (float)(color >> 24 & 255) / 255f;
        return new Color(R, G, B, A);
    }