예제 #1
0
        //set up platform specific items for this instance. Called once during creation.
        public void Setup()
        {
            //set locals
            _platformBuilder     = new PlatformBuilder();
            _platformBuilderCore = new PlatformBuilderCore(gameObject);
            _platformSections    = new List <PlatformSection>();
            strategies           = PlatformBuilder.GetStrategies();

            //add components
            meshFilter   = gameObject.AddComponent <MeshFilter> ();
            meshCollider = gameObject.AddComponent <MeshCollider>();
            meshRenderer = gameObject.AddComponent <MeshRenderer>();
        }
        /*
         * core method to update the mesh
         * passes in the platformBuilder instance to run the active strategy
         */
        public CombineInstance[] UpdatePlatform(PlatformBuilder platformBuilder)
        {
            var platform = _gameObject.GetComponent <Platform>();
            var points   = platform.GetPoints();

            //run current strategy before building mesh
            var updateInfo = platformBuilder.Update(points);

            //check if we should run an update
            if (!updateInfo.shouldUpdate)
            {
                return(null);
            }

            points = updateInfo.points;

            //get verts from points
            vertMatrix = points.Select(x => x.Select(z => new Vert {
                Vector = z.transform.position, Children = z.Children.Select(y => y.transform.position).ToArray()
            }).ToArray()).ToArray();

            //check for any verts with child points and set them up as their own verts
            for (var i = 0; i < vertMatrix.Length; i++)
            {
                var vertList = new List <Vert>();
                var section  = vertMatrix[i];
                for (var k = 0; k < section.Length; k++)
                {
                    var point = section[k];
                    vertList.Add(point);
                    if (point.Children != null && point.Children.Length > 0)
                    {
                        vertList.AddRange(point.Children.Select(x => new Vert {
                            Vector = x
                        }));
                    }
                }
                vertMatrix[i] = vertList.ToArray();
            }

            //generate individual sub meshes, one rectangle at a time, and add them to the meshList
            var meshList = new List <Mesh>();
            var firstSectionLengthDistance = 0f;
            var firstSectionWidthDistance  = 0f;

            for (var i = 0; i < vertMatrix.Length - 1; i++)
            {
                var currentSection = vertMatrix[i];
                var nextSection    = vertMatrix[i + 1];

                for (var k = 0; k < currentSection.Length; k++)
                {
                    var nextIndex = 0;

                    if (k < currentSection.Length - 1)
                    {
                        nextIndex = k + 1;
                    }

                    var verts = new Vector3[4];
                    verts[3] = currentSection[k].Vector;
                    verts[2] = currentSection[nextIndex].Vector;
                    verts[1] = nextSection[nextIndex].Vector;
                    verts[0] = nextSection[k].Vector;

                    //track the first section distance between first points
                    if (i == 0)
                    {
                        firstSectionLengthDistance = Mathf.Abs(Vector3.Distance(currentSection[k].Vector, nextSection[k].Vector));
                    }
                    if (k == 0)
                    {
                        firstSectionWidthDistance = Mathf.Abs(Vector3.Distance(currentSection[k].Vector, currentSection[nextIndex].Vector));
                    }

                    var previousLengthUvs = new Vector2[] { new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f), new Vector2(0f, 0f) };
                    var previousWidthUvs  = new Vector2[] { new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(0f, 1f), new Vector2(0f, 0f) };

                    if (i > 0)
                    {
                        previousLengthUvs = meshList[meshList.Count - currentSection.Length].uv;
                    }
                    if (k > 0)
                    {
                        previousWidthUvs = meshList[meshList.Count - 1].uv;
                    }
                    meshList.Add(GenerateMeshFromPoints(verts, firstSectionLengthDistance, firstSectionWidthDistance, previousLengthUvs, previousWidthUvs));
                }
            }

            //combine mesh sides through entire platform
            var sideLength  = vertMatrix[0].Length;
            var subMeshList = new List <Mesh>();

            for (var i = 0; i < sideLength; i++)
            {
                var index          = 0;
                var combineSubMesh = new CombineInstance[vertMatrix.Length - 1];
                for (var k = i; k < meshList.Count; k = k + sideLength)
                {
                    combineSubMesh[index].mesh      = meshList[k];
                    combineSubMesh[index].transform = Matrix4x4.identity;
                    index++;
                }
                var mesh = new Mesh();
                mesh.CombineMeshes(combineSubMesh);
                subMeshList.Add(mesh);
            }

            //combine child meshes with parent mesh (so they share the same material)
            var parentVerts = vertMatrix[0].Where(x => x.Children != null && x.Children.Length > 0).ToArray();

            for (var i = 0; i < parentVerts.Length; i++)
            {
                var parentSubmeshIndex = Array.IndexOf(vertMatrix[0], parentVerts[i]);
                var childSubmeshes     = subMeshList.GetRange(parentSubmeshIndex + 1, parentVerts[i].Children.Count() + 1);
                var parentSubMesh      = subMeshList[parentSubmeshIndex];

                var combineSubMesh = new CombineInstance[childSubmeshes.Count + 1];
                combineSubMesh[0].mesh      = parentSubMesh;
                combineSubMesh[0].transform = Matrix4x4.identity;

                for (var k = 0; k < childSubmeshes.Count; k++)
                {
                    combineSubMesh[k + 1].mesh      = childSubmeshes[k];
                    combineSubMesh[k + 1].transform = Matrix4x4.identity;
                }
                var mesh = new Mesh();
                mesh.CombineMeshes(combineSubMesh);
                subMeshList[parentSubmeshIndex] = mesh;
            }

            //since the child meshes were combined with the parent, remove them from the list of meshes
            var subMeshes = new List <Mesh>();

            for (var i = 0; i < subMeshList.Count(); i++)
            {
                if (vertMatrix[0][i].Children != null && vertMatrix[0][i].Children.Count() > 0)
                {
                    subMeshes.Add(subMeshList[i]);
                    i = Array.IndexOf(vertMatrix[0], vertMatrix[0][i]) + 1 + vertMatrix[0][i].Children.Count();
                }
                else
                {
                    subMeshes.Add(subMeshList[i]);
                }
            }

            //set up end caps
            subMeshes.Add(GenerateEndCaps(vertMatrix[0], true));
            subMeshes.Add(GenerateEndCaps(vertMatrix[vertMatrix.Length - 1], false));

            //combine all sub meshes
            var combine = new CombineInstance[subMeshes.Count];

            for (var i = 0; i < combine.Length; i++)
            {
                combine[i].mesh      = subMeshes[i];
                combine[i].transform = _gameObject.transform.worldToLocalMatrix;
            }
            return(combine);
        }