private void AddGameObjectsTo(GameObject parent, XElement xml, bool isParentTrigger, string objPath, IList <ICustomTiledImporter> customImporters) { foreach (XElement goXml in xml.Elements("GameObject")) { string name = ImportUtils.GetAttributeAsString(goXml, "name", ""); string copyFrom = ImportUtils.GetAttributeAsString(goXml, "copy", ""); GameObject child = null; if (!String.IsNullOrEmpty(copyFrom)) { float opacity = ImportUtils.GetAttributeAsFloat(goXml, "opacity", 1); child = CreateCopyFromMeshObj(copyFrom, objPath, opacity); if (child == null) { // We're in trouble. Errors should already be in the log. return; } // Apply the sorting to the renderer of the mesh object we just copied into the child Renderer renderer = child.GetComponent <Renderer>(); string sortingLayer = ImportUtils.GetAttributeAsString(goXml, "sortingLayerName", ""); if (!String.IsNullOrEmpty(sortingLayer) && !SortingLayerExposedEditor.GetSortingLayerNames().Contains(sortingLayer)) { Debug.LogError(string.Format("Sorting Layer \"{0}\" does not exist. Check your Project Settings -> Tags and Layers", sortingLayer)); renderer.sortingLayerName = "Default"; } else { renderer.sortingLayerName = sortingLayer; } // Set the sorting order renderer.sortingOrder = ImportUtils.GetAttributeAsInt(goXml, "sortingOrder", 0); } else { child = new GameObject(); } if (!String.IsNullOrEmpty(name)) { child.name = name; } // Assign the child to the parent child.transform.parent = parent.transform; // Set the position float x = ImportUtils.GetAttributeAsFloat(goXml, "x", 0); float y = ImportUtils.GetAttributeAsFloat(goXml, "y", 0); child.transform.localPosition = new Vector3(x, y, 0); // Add any tile animators AddTileAnimatorsTo(child, goXml); // Do we have any collision data? // Check if we are setting 'isTrigger' for ourselves or for our childen bool isTrigger = ImportUtils.GetAttributeAsBoolean(goXml, "isTrigger", isParentTrigger); AddCollidersTo(child, isTrigger, goXml); // Do we have any children of our own? AddGameObjectsTo(child, goXml, isTrigger, objPath, customImporters); // Does this game object have a tag? AssignTagTo(child, goXml); // Does this game object have a layer? AssignLayerTo(child, goXml); // Are there any custom properties? HandleCustomProperties(child, goXml, customImporters); // Set scale and rotation *after* children are added otherwise Unity will have child+parent transform cancel each other out float sx = ImportUtils.GetAttributeAsFloat(goXml, "scaleX", 1.0f); float sy = ImportUtils.GetAttributeAsFloat(goXml, "scaleY", 1.0f); child.transform.localScale = new Vector3(sx, sy, 1.0f); // Set the rotation // Use negative rotation on the z component because of change in coordinate systems between Tiled and Unity Vector3 localRotation = new Vector3(); localRotation.x = (ImportUtils.GetAttributeAsBoolean(goXml, "flipY", false) == true) ? 180.0f : 0.0f; localRotation.y = (ImportUtils.GetAttributeAsBoolean(goXml, "flipX", false) == true) ? 180.0f : 0.0f; localRotation.z = -ImportUtils.GetAttributeAsFloat(goXml, "rotation", 0); child.transform.eulerAngles = localRotation; } }
// We need to call this while the renderers on the model is having its material assigned to it public Material FixMaterialForMeshRenderer(string objName, Renderer renderer) { string xmlPath = ImportUtils.GetXmlPath(objName); XDocument xml = XDocument.Load(xmlPath); // The mesh to match string meshName = renderer.name; // The mesh name may be decorated by Unity string pattern = @"_MeshPart[\d]$"; Regex regex = new Regex(pattern); meshName = regex.Replace(meshName, ""); var assignMaterials = xml.Root.Elements("AssignMaterial"); // Find an assignment that matches the mesh renderer XElement match = assignMaterials.FirstOrDefault(el => el.Attribute("mesh").Value == meshName); if (match == null) { // The names of our meshes in the AssignMaterials elements may be wrong // This happened before when Unity replaced whitespace with underscore in our named meshes // That case is handled now, but there may be others StringBuilder builder = new StringBuilder(); builder.AppendFormat("Could not find mesh named '{0}' for material matching\n", renderer.name); string choices = String.Join("\n ", assignMaterials.Select(m => m.Attribute("mesh").Value).ToArray()); builder.AppendFormat("Choices are:\n {0}", choices); Debug.LogError(builder.ToString()); return(null); } string materialName = match.Attribute("material").Value; string materialPath = ImportUtils.GetMaterialPath(materialName); // Assign the material renderer.sharedMaterial = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material; // Set the sorting layer for the mesh string sortingLayer = match.Attribute("sortingLayerName").Value; if (!String.IsNullOrEmpty(sortingLayer) && !SortingLayerExposedEditor.GetSortingLayerNames().Contains(sortingLayer)) { Debug.LogError(string.Format("Sorting Layer \"{0}\" does not exist. Check your Project Settings -> Tags and Layers", sortingLayer)); renderer.sortingLayerName = "Default"; } else { renderer.sortingLayerName = sortingLayer; } // Set the sorting order renderer.sortingOrder = ImportUtils.GetAttributeAsInt(match, "sortingOrder"); // Do we have an alpha color key? string htmlColor = ImportUtils.GetAttributeAsString(match, "alphaColorKey", ""); if (!String.IsNullOrEmpty(htmlColor)) { // Take for granted color is in the form '#RRGGBB' byte r = byte.Parse(htmlColor.Substring(1, 2), System.Globalization.NumberStyles.HexNumber); byte g = byte.Parse(htmlColor.Substring(3, 2), System.Globalization.NumberStyles.HexNumber); byte b = byte.Parse(htmlColor.Substring(5, 2), System.Globalization.NumberStyles.HexNumber); Color color = new Color32(r, g, b, 255); renderer.sharedMaterial.SetColor("_AlphaColorKey", color); } return(renderer.sharedMaterial); }
private void AddGameObjectsTo(GameObject parent, XElement xml, bool isParentTrigger, string objPath, IList <ICustomTiledImporter> customImporters) { foreach (XElement goXml in xml.Elements("GameObject")) { string name = ImportUtils.GetAttributeAsString(goXml, "name", ""); string copyFrom = ImportUtils.GetAttributeAsString(goXml, "copy", ""); GameObject child = null; if (!String.IsNullOrEmpty(copyFrom)) { child = CreateCopyFromMeshObj(copyFrom, objPath); if (child == null) { // We're in trouble. Errors should already be in the log. return; } } else { child = new GameObject(); } if (!String.IsNullOrEmpty(name)) { child.name = name; } // Set the position float x = ImportUtils.GetAttributeAsFloat(goXml, "x", 0); float y = ImportUtils.GetAttributeAsFloat(goXml, "y", 0); child.transform.position = new Vector3(x, y, 0); // Set the rotation float r = ImportUtils.GetAttributeAsFloat(goXml, "rotation", 0); if (r != 0) { // Use negative 'r' because of change in coordinate systems between Tiled and Unity child.transform.eulerAngles = new Vector3(0, 0, -r); } // Assign the child to the parent child.transform.parent = parent.transform; // Add any tile animators AddTileAnimatorsTo(child, goXml); // Do we have any collision data? // Check if we are setting 'isTrigger' for ourselves or for our childen bool isTrigger = ImportUtils.GetAttributeAsBoolean(goXml, "isTrigger", isParentTrigger); AddCollidersTo(child, isTrigger, goXml); // Do we have any children of our own? AddGameObjectsTo(child, goXml, isTrigger, objPath, customImporters); // Does this game object have a tag? AssignTagTo(child, goXml); // Does this game object have a layer? AssignLayerTo(child, goXml); // Are there any custom properties? HandleCustomProperties(child, goXml, customImporters); } }
private void ImportAllMaterials(Tiled2Unity.ImportBehaviour importComponent) { // Create a material for each texture that has been imported foreach (var xmlTexture in importComponent.XmlDocument.Root.Elements("ImportTexture")) { bool isResource = ImportUtils.GetAttributeAsBoolean(xmlTexture, "isResource", false); string textureFile = ImportUtils.GetAttributeAsString(xmlTexture, "filename"); string materialPath = MakeMaterialAssetPath(textureFile, isResource); string materialFile = System.IO.Path.GetFileName(materialPath); // Keep track that we importing this material if (!importComponent.ImportWait_Materials.Contains(materialFile)) { importComponent.ImportWait_Materials.Add(materialFile); } // Create the material UnityEngine.Material material = CreateMaterialFromXml(xmlTexture); // Assign the texture to the material { string textureAsset = GetTextureAssetPath(textureFile); AssignTextureAssetToMaterial(material, materialFile, textureAsset, importComponent); } ImportUtils.ReadyToWrite(materialPath); ImportUtils.CreateOrReplaceAsset(material, materialPath); importComponent.ImportTiled2UnityAsset(materialPath); } // Create a material for each internal texture foreach (var xmlInternal in importComponent.XmlDocument.Root.Elements("InternalTexture")) { bool isResource = ImportUtils.GetAttributeAsBoolean(xmlInternal, "isResource", false); string textureAsset = ImportUtils.GetAttributeAsString(xmlInternal, "assetPath"); string textureFile = System.IO.Path.GetFileName(textureAsset); string materialPath = MakeMaterialAssetPath(textureFile, isResource); string materialFile = System.IO.Path.GetFileName(materialPath); // Keep track that we importing this material if (!importComponent.ImportWait_Materials.Contains(materialFile)) { importComponent.ImportWait_Materials.Add(materialFile); } // Create the material and assign the texture UnityEngine.Material material = CreateMaterialFromXml(xmlInternal); AssignTextureAssetToMaterial(material, materialFile, textureAsset, importComponent); ImportUtils.ReadyToWrite(materialPath); ImportUtils.CreateOrReplaceAsset(material, materialPath); importComponent.ImportTiled2UnityAsset(materialPath); } // If we have no materials to import then go to next stage (meshes) if (importComponent.ImportWait_Materials.Count() == 0) { ImportAllMeshes(importComponent); } }
private void ImportAllMaterials(Tiled2Unity.ImportBehaviour importComponent) { // Create a material for each texture that has been imported foreach (var xmlTexture in importComponent.XmlDocument.Root.Elements("ImportTexture")) { bool isResource = ImportUtils.GetAttributeAsBoolean(xmlTexture, "isResource", false); string textureFile = ImportUtils.GetAttributeAsString(xmlTexture, "filename"); string materialPath = MakeMaterialAssetPath(textureFile, isResource); string materialFile = System.IO.Path.GetFileName(materialPath); // Keep track that we importing this material if (!importComponent.ImportWait_Materials.Contains(materialFile, StringComparer.OrdinalIgnoreCase)) { importComponent.ImportWait_Materials.Add(materialFile); } // Create the material UnityEngine.Material material = CreateMaterialFromXml(xmlTexture, importComponent); // Assign the texture to the material { string textureAsset = GetTextureAssetPath(textureFile); AssignTextureAssetToMaterial(material, materialFile, textureAsset, importComponent); } ImportUtils.ReadyToWrite(materialPath); ImportUtils.CreateOrReplaceAsset(material, materialPath); importComponent.ImportTiled2UnityAsset(materialPath); } // Create a material for each internal texture foreach (var xmlInternal in importComponent.XmlDocument.Root.Elements("InternalTexture")) { bool isResource = ImportUtils.GetAttributeAsBoolean(xmlInternal, "isResource", false); string textureAsset = ImportUtils.GetAttributeAsString(xmlInternal, "assetPath"); string textureFile = System.IO.Path.GetFileName(textureAsset); string materialPath = MakeMaterialAssetPath(textureFile, isResource); // "Internal textures" may have a unique material name that goes with it string uniqueMaterialName = ImportUtils.GetAttributeAsString(xmlInternal, "materialName", ""); if (!String.IsNullOrEmpty(uniqueMaterialName)) { materialPath = String.Format("{0}/{1}{2}", Path.GetDirectoryName(materialPath), uniqueMaterialName, Path.GetExtension(materialPath)); materialPath = materialPath.Replace(System.IO.Path.DirectorySeparatorChar, '/'); } string materialFile = System.IO.Path.GetFileName(materialPath); // Keep track that we are importing this material if (!importComponent.ImportWait_Materials.Contains(materialFile, StringComparer.OrdinalIgnoreCase)) { importComponent.ImportWait_Materials.Add(materialFile); } // Create the material and assign the texture UnityEngine.Material material = CreateMaterialFromXml(xmlInternal, importComponent); AssignTextureAssetToMaterial(material, materialFile, textureAsset, importComponent); ImportUtils.ReadyToWrite(materialPath); ImportUtils.CreateOrReplaceAsset(material, materialPath); importComponent.ImportTiled2UnityAsset(materialPath); } // If we have no materials to import then go to next stage (meshes) if (importComponent.ImportWait_Materials.Count() == 0) { ImportAllMeshes(importComponent); } }
private void AddGameObjectsTo(GameObject parent, XElement xml, bool isParentTrigger, ImportBehaviour importComponent, IList <ICustomTiledImporter> customImporters) { foreach (XElement goXml in xml.Elements("GameObject")) { string name = ImportUtils.GetAttributeAsString(goXml, "name", ""); string copyFrom = ImportUtils.GetAttributeAsString(goXml, "copy", ""); string mesh = ImportUtils.GetAttributeAsString(goXml, "mesh", ""); GameObject child = null; if (!String.IsNullOrEmpty(mesh)) { child = CreateGameObjectWithMesh(mesh, importComponent); } else if (!String.IsNullOrEmpty(copyFrom)) { child = CreateCopyFromMeshObj(copyFrom, importComponent); } else { child = new GameObject(); } if (child == null) { importComponent.RecordError("Error creating child object '{0}'", name); return; } // Assign the given name to our child if (!String.IsNullOrEmpty(name)) { child.name = name; } // Assign the child to the parent child.transform.parent = parent.transform; // Set the position float x = ImportUtils.GetAttributeAsFloat(goXml, "x", 0); float y = ImportUtils.GetAttributeAsFloat(goXml, "y", 0); float z = ImportUtils.GetAttributeAsFloat(goXml, "z", 0); child.transform.localPosition = new Vector3(x, y, z); // Add any layer components AddTileLayerComponentsTo(child, goXml); AddObjectLayerComponentsTo(child, goXml); AddGroupLayerComponentsTo(child, goXml); // Add any object group items AddTmxObjectComponentsTo(child, goXml); AddRectangleObjectComponentsTo(child, goXml); AddCircleObjectComponentsTo(child, goXml); AddPolygonObjectComponentsTo(child, goXml); AddPolylineObjectComponentsTo(child, goXml); AddTileObjectComponentsTo(child, goXml); // Add any tile animators AddTileAnimatorsTo(child, goXml); // Do we have any collision data? // Check if we are setting 'isTrigger' for ourselves or for our children bool isTrigger = ImportUtils.GetAttributeAsBoolean(goXml, "isTrigger", isParentTrigger); AddCollidersTo(child, isTrigger, goXml); // Do we have any children of our own? AddGameObjectsTo(child, goXml, isTrigger, importComponent, customImporters); // Does this game object have a tag? AssignTagTo(child, goXml, importComponent); // Does this game object have a layer? AssignLayerTo(child, goXml, importComponent); // Assign from various attributes AssignOpacityTo(child, goXml, importComponent); AssignSortingLayerNameTo(child, goXml, importComponent); AssignSortingOrderTo(child, goXml, importComponent); // Set scale and rotation *after* children are added otherwise Unity will have child+parent transform cancel each other out float sx = ImportUtils.GetAttributeAsFloat(goXml, "scaleX", 1.0f); float sy = ImportUtils.GetAttributeAsFloat(goXml, "scaleY", 1.0f); child.transform.localScale = new Vector3(sx, sy, 1.0f); // Set the rotation // Use negative rotation on the z component because of change in coordinate systems between Tiled and Unity Vector3 localRotation = new Vector3(); localRotation.z = -ImportUtils.GetAttributeAsFloat(goXml, "rotation", 0); child.transform.eulerAngles = localRotation; // Are there any custom properties? (This comes last - after all transformations have taken place.) HandleCustomProperties(child, goXml, customImporters); } }