public Mesh CreateColliderMesh() { // We use the currentLayer ID to order them on the Z axis. // Be aware that on the collider mesh it depends on the freezeColliderLayers // variable, this way you can avoid having colliders on different z axis. int currentLayerID = 0; // UsedVertices is used to maintain a count of the vertices between // layers so when you call renderTriangles, it nows where to start. int usedVertices = 0; TileSet tileset = null; List<Vector3> vertices = new List<Vector3> (); List<int> triangles = new List<int> (); Mesh mesh = new Mesh (); XmlDocument xmldoc = new XmlDocument (); xmldoc.Load (new StringReader (tilemap.text)); XmlNodeList nodelist = xmldoc.DocumentElement.ChildNodes; // Works the almost the same way as the createMesh method (builds the // tileset and layer objects, then builds the mesh with those // but only checks on the collision names plus it doesn't build model // uv since its not neccesary. foreach (XmlNode outerNode in nodelist) { switch (outerNode.Name) { case "tileset": if (outerNode.Attributes ["name"].InnerText.IndexOf ("Collision") != -1) { XmlNode imageNode = outerNode.SelectSingleNode ("image"); int firstGID = int.Parse (outerNode.Attributes ["firstgid"].InnerText); int width = int.Parse (outerNode.Attributes ["tilewidth"].InnerText); int height = int.Parse (outerNode.Attributes ["tileheight"].InnerText); int imageWidth = int.Parse (imageNode.Attributes ["width"].InnerText); int imageheight = int.Parse (imageNode.Attributes ["height"].InnerText); tileset = new TileSet (firstGID, width, height, imageWidth, imageheight); // On the TMX editor, we set some attributes on our collider tiles so when parsing the // tileset, we'll be adding them to our tileset object. foreach (XmlNode innerNode in outerNode.ChildNodes) { if (innerNode.Name == "tile") { int tileID = 0; if (int.TryParse (innerNode.Attributes ["id"].InnerText, out tileID)) { XmlNode propertyNodes = innerNode.SelectSingleNode ("properties"); foreach (XmlNode propertyNode in propertyNodes) { if (propertyNode.Attributes ["name"].InnerText == "col") { tileset.AddCollision (tileID, propertyNode.Attributes ["value"].InnerText); } } } } } } break; case "layer": if (outerNode.Attributes ["name"].InnerText.IndexOf ("collision_") != -1) { XmlNode dataNode = outerNode.SelectSingleNode ("data"); int layerWidth = int.Parse (outerNode.Attributes ["width"].InnerText); int layerHeight = int.Parse (outerNode.Attributes ["height"].InnerText); string csvData = dataNode.InnerText; Layer currentLayer = new Layer (tileset, csvData, currentLayerID, layerWidth, layerHeight); vertices.AddRange (currentLayer.renderColVertices ()); triangles.AddRange (currentLayer.renderTriangles (usedVertices, usedVertices + currentLayer.vertexCount)); usedVertices += currentLayer.vertexCount; // In case we freeze the layers on collider they wont move on the z axis. } if (!freezeLayersOnCollider) currentLayerID++; break; case "objectgroup": if (outerNode.Attributes ["name"].InnerText.IndexOf ("CollisionObjects") != -1) { foreach (XmlNode objectNode in outerNode.ChildNodes) { int colliderWidth = 0; int colliderHeight = 0; if (objectNode.Attributes.GetNamedItem ("width") != null) { colliderWidth = int.Parse (objectNode.Attributes ["width"].InnerText); colliderHeight = int.Parse (objectNode.Attributes ["height"].InnerText); } int colliderX = int.Parse (objectNode.Attributes ["x"].InnerText); int colliderY = int.Parse (objectNode.Attributes ["y"].InnerText); colliderX += (colliderWidth / 2 + 16); colliderY = - (colliderY + colliderHeight / 2); GameObject newCollider = null; if (objectNode.HasChildNodes) { // Can be polyline, ellipse or polygon, as boxes have no child. string objectType = objectNode.FirstChild.Name; Debug.Log ("Has children: " + objectType); switch (objectType) { case "ellipse": newCollider = CreateEllipseCollider (colliderX, colliderY, colliderWidth, colliderHeight); break; case "polyline": XmlNode polylineData = objectNode.FirstChild; newCollider = CreatePolylineCollider (polylineData, colliderX, colliderY); break; case "polygon": default: break; } } else { // Box newCollider = CreateBoxCollider (colliderX, colliderY, colliderWidth, colliderHeight); } if (newCollider != null) { if (transform.FindChild ("Colliders") == null) { GameObject colliderContainer = new GameObject ("Colliders"); colliderContainer.transform.parent = gameObject.transform; } newCollider.transform.parent = transform.FindChild ("Colliders").transform; } } } break; } } mesh.vertices = vertices.ToArray (); mesh.triangles = triangles.ToArray (); return mesh; }
public Mesh CreateColliderMesh() { // We use the currentLayer ID to order them on the Z axis. // Be aware that on the collider mesh it depends on the freezeColliderLayers // variable, this way you can avoid having colliders on different z axis. int currentLayerID = 0; // UsedVertices is used to maintain a count of the vertices between // layers so when you call renderTriangles, it nows where to start. int usedVertices = 0; TileSet tileset = null; List <Vector3> vertices = new List <Vector3> (); List <int> triangles = new List <int> (); Mesh mesh = new Mesh(); XmlDocument xmldoc = new XmlDocument(); xmldoc.Load(new StringReader(tilemap.text)); XmlNodeList nodelist = xmldoc.DocumentElement.ChildNodes; // Works the almost the same way as the createMesh method (builds the // tileset and layer objects, then builds the mesh with those // but only checks on the collision names plus it doesn't build model // uv since its not neccesary. foreach (XmlNode outerNode in nodelist) { switch (outerNode.Name) { case "tileset": if (outerNode.Attributes ["name"].InnerText.IndexOf("Collision") != -1) { XmlNode imageNode = outerNode.SelectSingleNode("image"); int firstGID = int.Parse(outerNode.Attributes ["firstgid"].InnerText); int width = int.Parse(outerNode.Attributes ["tilewidth"].InnerText); int height = int.Parse(outerNode.Attributes ["tileheight"].InnerText); int imageWidth = int.Parse(imageNode.Attributes ["width"].InnerText); int imageheight = int.Parse(imageNode.Attributes ["height"].InnerText); tileset = new TileSet(firstGID, width, height, imageWidth, imageheight); // On the TMX editor, we set some attributes on our collider tiles so when parsing the // tileset, we'll be adding them to our tileset object. foreach (XmlNode innerNode in outerNode.ChildNodes) { if (innerNode.Name == "tile") { int tileID = 0; if (int.TryParse(innerNode.Attributes ["id"].InnerText, out tileID)) { XmlNode propertyNodes = innerNode.SelectSingleNode("properties"); foreach (XmlNode propertyNode in propertyNodes) { if (propertyNode.Attributes ["name"].InnerText == "col") { tileset.AddCollision(tileID, propertyNode.Attributes ["value"].InnerText); } } } } } } break; case "layer": if (outerNode.Attributes ["name"].InnerText.IndexOf("collision_") != -1) { XmlNode dataNode = outerNode.SelectSingleNode("data"); int layerWidth = int.Parse(outerNode.Attributes ["width"].InnerText); int layerHeight = int.Parse(outerNode.Attributes ["height"].InnerText); string csvData = dataNode.InnerText; Layer currentLayer = new Layer(tileset, csvData, currentLayerID, layerWidth, layerHeight); vertices.AddRange(currentLayer.renderColVertices()); triangles.AddRange(currentLayer.renderTriangles(usedVertices, usedVertices + currentLayer.vertexCount)); usedVertices += currentLayer.vertexCount; // In case we freeze the layers on collider they wont move on the z axis. } if (!freezeLayersOnCollider) { currentLayerID++; } break; case "objectgroup": if (outerNode.Attributes ["name"].InnerText.IndexOf("CollisionObjects") != -1) { foreach (XmlNode objectNode in outerNode.ChildNodes) { int colliderWidth = 0; int colliderHeight = 0; if (objectNode.Attributes.GetNamedItem("width") != null) { colliderWidth = int.Parse(objectNode.Attributes ["width"].InnerText); colliderHeight = int.Parse(objectNode.Attributes ["height"].InnerText); } int colliderX = int.Parse(objectNode.Attributes ["x"].InnerText); int colliderY = int.Parse(objectNode.Attributes ["y"].InnerText); colliderX += (colliderWidth / 2 + 16); colliderY = -(colliderY + colliderHeight / 2); GameObject newCollider = null; if (objectNode.HasChildNodes) { // Can be polyline, ellipse or polygon, as boxes have no child. string objectType = objectNode.FirstChild.Name; Debug.Log("Has children: " + objectType); switch (objectType) { case "ellipse": newCollider = CreateEllipseCollider(colliderX, colliderY, colliderWidth, colliderHeight); break; case "polyline": XmlNode polylineData = objectNode.FirstChild; newCollider = CreatePolylineCollider(polylineData, colliderX, colliderY); break; case "polygon": default: break; } } else { // Box newCollider = CreateBoxCollider(colliderX, colliderY, colliderWidth, colliderHeight); } if (newCollider != null) { if (transform.FindChild("Colliders") == null) { GameObject colliderContainer = new GameObject("Colliders"); colliderContainer.transform.parent = gameObject.transform; } newCollider.transform.parent = transform.FindChild("Colliders").transform; } } } break; } } mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); return(mesh); }