Commits

PolCPP committed 2dfc2da Merge

Merged in daviderosa/unitmx/object_layer_support (pull request #2)

Add objects layers support. Allowing to define collisions using rectangles ellipses and polylines (polygons in the future) in a layer called "CollisionObjects".

  • Participants
  • Parent commits aa85e80, 5ebba91

Comments (0)

Files changed (2)

 					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));
+					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;		
 	}	
+	private GameObject CreateBoxCollider (int colliderX, int colliderY, int colliderWidth, int colliderHeight)
+	{
+		Debug.Log ("Creating box at " + colliderX + ", " + colliderY);
+		GameObject cube = new GameObject ("Collider_box_" + colliderX + colliderY);
+		BoxCollider collider = cube.AddComponent (typeof(BoxCollider)) as BoxCollider;
+		cube.transform.localPosition = new Vector3 (colliderX, colliderY, 0);
+		collider.size = new Vector3 (colliderWidth, colliderHeight, 10.0f);
+		
+		return cube;
+	}
 	
+	private GameObject CreateEllipseCollider (int colliderX, int colliderY, int colliderWidth, int colliderHeight)
+	{
+		Debug.Log ("Creating ellypse collider at " + colliderX + ", " + colliderY);
+		if (colliderWidth != colliderHeight) {
+			// We are simulating the ellipse with a capsule collider, which cannot 
+			// be as accurate as a real ellypse...
+			Debug.LogWarning ("Ellypse colliders are not really accurate when not round.");
+		}
+		GameObject ellipse = new GameObject ("Collider_ellipse_" + colliderX + colliderY);
+		CapsuleCollider collider = ellipse.AddComponent (typeof(CapsuleCollider)) as CapsuleCollider;
+		ellipse.transform.localPosition = new Vector3 (colliderX, colliderY, 0);
+		if (colliderWidth >= colliderHeight) {
+			collider.direction = 0;
+			collider.radius = colliderHeight / 2.0f;
+			collider.height = colliderWidth;
+		} else {
+			collider.direction = 1;
+			collider.radius = colliderWidth / 2.0f;
+			collider.height = colliderHeight;
+		}
+
+		return ellipse;		
+	}
 	
+	private GameObject CreatePolylineCollider (XmlNode data, int colliderX, int colliderY)
+	{
+		GameObject polyline = new GameObject ("Collider_polyline" + colliderX + colliderY);
+		Mesh mesh = new Mesh ();
+		polyline.AddComponent<MeshCollider> ();
+//		polyline.AddComponent<MeshFilter> ();
+//		polyline.AddComponent<MeshRenderer> ();
+		
+		ArrayList points = new ArrayList ();
+		List<Vector3> vertices = new List<Vector3> ();
+		List<int> verticesOrder = new List<int> ();
+		
+		string pointsString = data.Attributes ["points"].InnerText;
+		string [] pointsTuples = pointsString.Split (' ');
+		
+		foreach (string p in pointsTuples) {
+			Vector3 point = new Vector3 ();
+			string[] tmp = p.Split (',');
+			point.x = colliderX + int.Parse (tmp [0]);
+			point.y = colliderY - int.Parse (tmp [1]);
+			point.z = 0.0f;
+			points.Add (point);
+			Debug.Log ("Adding point: " + point.ToString ());
+		}
+		
+		Vector3 firstPoint = (Vector3)points [0];
+		for (int idx=1; idx < points.Count; idx++) {
+			Vector3 secondPoint = (Vector3)points [idx];
+			Vector3 firstFront = new Vector3 (firstPoint.x, firstPoint.y, -10.0f);
+			Vector3 firstBack = new Vector3 (firstPoint.x, firstPoint.y, 10.0f);
+			Vector3 secondFront = new Vector3 (secondPoint.x, secondPoint.y, -10.0f);
+			Vector3 secondBack = new Vector3 (secondPoint.x, secondPoint.y, 10.0f);
+			vertices.Add (firstFront); // 0
+			vertices.Add (firstBack); // 1
+			vertices.Add (secondFront); // 2
+			vertices.Add (secondBack); // 3
+			
+			verticesOrder.Add ((idx - 1) * 4 + 0);
+			verticesOrder.Add ((idx - 1) * 4 + 1);
+			verticesOrder.Add ((idx - 1) * 4 + 3);
+
+			verticesOrder.Add ((idx - 1) * 4 + 3);
+			verticesOrder.Add ((idx - 1) * 4 + 2);
+			verticesOrder.Add ((idx - 1) * 4 + 0);
+
+			firstPoint = secondPoint;
+		}
+		
+		mesh.vertices = vertices.ToArray ();
+		mesh.triangles = verticesOrder.ToArray ();
+		
+		mesh.RecalculateNormals ();
+		
+		polyline.GetComponent<MeshCollider> ().sharedMesh = mesh;
+//		polyline.GetComponent<MeshFilter> ().mesh = mesh;
+		
+		return polyline;
+	}
 }

Editor/TileMapEditor.cs

 			MeshCollider collider = TMap.GetComponent<MeshCollider>();
 			if (collider)
 				DestroyImmediate(collider, true);
+			if(TMap.transform.FindChild("Colliders") != null){
+				DestroyImmediate(TMap.transform.FindChild("Colliders").gameObject, true);
+			}
 			collider = TMap.gameObject.AddComponent<MeshCollider>();
 			collider.sharedMesh = TMap.CreateColliderMesh();		
 		}