如何创建在Unity中与网格一起生成的Box Collider2D?

时间:2018-07-31 00:01:17

标签: c# unity3d game-physics

所以我正在使用的代码在下面(Unity中的C#)

using System.Collections.Generic;
using UnityEngine;

    [RequireComponent(typeof(MeshFilter))]
    public class PolygonGenerator : MonoBehaviour
    {
        public List<Vector3> newVertices = new List<Vector3>();
        public List<int> newTriangles = new List<int>();
        public List<Vector2> newUV = new List<Vector2>();

        private Mesh mesh;

        private float tUnitY = 0.33333f;     //These are just objects I've given IDs for textures
        private float tUnitX = 0.166667f;
        private Vector2 tDirtBL = new Vector2(0, 0);
        private Vector2 tDirtB = new Vector2(1, 0);
        private Vector2 tDirtBR = new Vector2(2, 0);
        private Vector2 tDirtL = new Vector2(0, 1);
        private Vector2 tDirt = new Vector2(1, 1);
        private Vector2 tDirtR = new Vector2(2, 1);
        private Vector2 tDirtUL = new Vector2(0, 2);
        private Vector2 tDirtU = new Vector2(1, 2);
        private Vector2 tDirtUR = new Vector2(2, 2);
        private Vector2 tStone = new Vector2(4, 1);

        private int squareCount;

        public byte[,] blocks;

        public List<Vector3> colVertices = new List<Vector3>();
        public List<int> colTriangles = new List<int>();
        private int colCount;

        private EdgeCollider2D col;

        void Start()
        {
            mesh = GetComponent<MeshFilter>().mesh;

            col = GetComponent<EdgeCollider2D>();

            float x = transform.position.x;
            float y = transform.position.y;
            float z = transform.position.z;

            GenTerrain();
            BuildMesh();
            MeshUpdate();
        }

        void GenSquare(int x, int y, Vector2 texture)    //This creates the blocks I can apply textures to
        {
            newVertices.Add(new Vector3(x, y, 0));
            newVertices.Add(new Vector3(x + 1, y, 0));
            newVertices.Add(new Vector3(x + 1, y - 1, 0));
            newVertices.Add(new Vector3(x, y - 1, 0));

             newTriangles.Add(squareCount * 4);
             newTriangles.Add((squareCount * 4) + 1);
             newTriangles.Add((squareCount * 4) + 3);
             newTriangles.Add((squareCount * 4) + 1);
             newTriangles.Add((squareCount * 4) + 2);
             newTriangles.Add((squareCount * 4) + 3);

             newUV.Add(new Vector2(tUnitX * texture.x, tUnitY * texture.y + tUnitY));
             newUV.Add(new Vector2(tUnitX * texture.x + tUnitX, tUnitY * texture.y + tUnitY));
             newUV.Add(new Vector2(tUnitX * texture.x + tUnitX, tUnitY * texture.y));
             newUV.Add(new Vector2(tUnitX * texture.x, tUnitY * texture.y));

             squareCount++;
         }

         void MeshUpdate()    //This merely updates the mesh
         {
             mesh.Clear();
             mesh.vertices = newVertices.ToArray();
             mesh.triangles = newTriangles.ToArray();
             mesh.uv = newUV.ToArray();
             mesh.RecalculateNormals();

             squareCount = 0;
             newVertices.Clear();
             newTriangles.Clear();
             newUV.Clear();

             Mesh newMesh = new Mesh();
             newMesh.vertices = colVertices.ToArray();
             newMesh.triangles = colTriangles.ToArray();
             col.sharedMaterial = newMesh;

             colVertices.Clear();
             colTriangles.Clear();
             colCount = 0;
         }

         void GenTerrain()    //Generates terrain based on parameters I supply and I can add in 
         {                    //PerlinNoise to create variable terrain instead of flat
             blocks = new byte[512, 128];

             for (int px = 0; px < blocks.GetLength(0); px++)  //Also tells which blocks are which
             {
                 int stone = Noise(px, 0, 80, 15, 1);
                 stone += Noise(px, 0, 50, 30, 1);
                 stone += Noise(px, 0, 10, 10, 1);
                 stone += 75;

            print(stone);

            int dirt = Noise(px, 0, 25f, 35, 1);
            dirt += Noise(px, 100, 50, 30, 1);
            dirt += 75;


            for (int py = 0; py < blocks.GetLength(1); py++)
            {
                if (py < stone)
                {
                    blocks[px, py] = 1;

                    //The next three lines make dirt spots in random places
                    if (Noise(px, py, 12, 16, 1) > 10)
                    {
                        blocks[px, py] = 2;

                    }

                    //The next three lines remove dirt and rock to make caves in certain places
                    if (Noise(px, py * 2, 16, 14, 1) > 10)
                    { //Caves
                        blocks[px, py] = 0;

                    }

                }
                else if (py < dirt)
                {
                    blocks[px, py] = 2;
                }


            }
        }
    }

    void BuildMesh()  //Mesh Creation
    {
        for (int px = 0; px < blocks.GetLength(0); px++)
        {
            for (int py = 0; py < blocks.GetLength(1); py++)
            {

                if (blocks[px, py] != 0)
                {
                    GenCollider(px, py);
                }

                if (blocks[px, py] == 1)
                {
                    GenSquare(px, py, tStone);
                }
                else if (blocks[px, py] == 2)
                {
                    GenSquare(px, py, tDirtU);
                }
            }
        }
    }

    void GenCollider(int x, int y)
    {
        //Top
        if (Block(x, y + 1) == 0)
        {
            colVertices.Add(new Vector3(x, y, 1));
            colVertices.Add(new Vector3(x + 1, y, 1));
            colVertices.Add(new Vector3(x + 1, y, 0));
            colVertices.Add(new Vector3(x, y, 0));

            ColliderTriangles();
            colCount++;
        }

        //Bottom
        if (Block(x, y - 1) == 0)
        {
            colVertices.Add(new Vector3(x, y - 1, 0));
            colVertices.Add(new Vector3(x + 1, y - 1, 0));
            colVertices.Add(new Vector3(x + 1, y - 1, 1));
            colVertices.Add(new Vector3(x, y - 1, 1));

            ColliderTriangles();
            colCount++;
        }

        //Left
        if (Block(x - 1, y) == 0)
        {
            colVertices.Add(new Vector3(x, y - 1, 1));
            colVertices.Add(new Vector3(x, y, 1));
            colVertices.Add(new Vector3(x, y, 0));
            colVertices.Add(new Vector3(x, y - 1, 0));

            ColliderTriangles();
            colCount++;
        }

        //Right
        if (Block(x + 1, y) == 0)
        {
            colVertices.Add(new Vector3(x + 1, y, 1));
            colVertices.Add(new Vector3(x + 1, y - 1, 1));
            colVertices.Add(new Vector3(x + 1, y - 1, 0));
            colVertices.Add(new Vector3(x + 1, y, 0));

            ColliderTriangles();
            colCount++;
        }
    }

    void ColliderTriangles()
    {
        colTriangles.Add(colCount * 4);
        colTriangles.Add((colCount * 4) + 1);
        colTriangles.Add((colCount * 4) + 3);
        colTriangles.Add((colCount * 4) + 1);
        colTriangles.Add((colCount * 4) + 2);
        colTriangles.Add((colCount * 4) + 3);
    }

    byte Block(int x, int y)
    {
        if (x == -1 || x == blocks.GetLength(0) || y == -1 || y == blocks.GetLength(1))
        {
            return (byte)1;
        }

        return blocks[x, y];
    }

    int Noise(int x, int y, float scale, float mag, float exp)
    {
        return (int)(Mathf.Pow((Mathf.PerlinNoise(x / scale, y / scale) * mag), (exp)));
    }
}

为适应BoxCollider2D,已对代码进行了原始修改,但给我一个错误。该脚本与“网格滤镜”,“网格碰撞器”(试图将其替换为2D游戏的盒子碰撞器)以及在Unity中创建的“空白”上的网格渲染器一起使用。

我是否可以使用任何可行的解决方案,而不是在瓦片旁边生成网格碰撞器,以便使盒碰撞器生成?如果需要更多详细信息,请询问。

0 个答案:

没有答案