private void CreatePrefab(XElement xmlPrefab, Tiled2Unity.ImportBehaviour importComponent)
        {
            var customImporters = GetCustomImporterInstances(importComponent);

            // Part 1: Create the prefab
            string     prefabName  = xmlPrefab.Attribute("name").Value;
            float      prefabScale = ImportUtils.GetAttributeAsFloat(xmlPrefab, "scale", 1.0f);
            GameObject tempPrefab  = new GameObject(prefabName);

            HandleTiledAttributes(tempPrefab, xmlPrefab, importComponent);
            HandleCustomProperties(tempPrefab, xmlPrefab, customImporters);

            // 한도영!
            {
                tempPrefab.tag = "Map";
                tempPrefab.AddComponent <Map>();
            }

            // Part 2: Build out the prefab
            // We may have an 'isTrigger' attribute that we want our children to obey
            bool isTrigger = ImportUtils.GetAttributeAsBoolean(xmlPrefab, "isTrigger", false);

            AddGameObjectsTo(tempPrefab, xmlPrefab, isTrigger, importComponent, customImporters);

            // Part 3: Allow for customization from other editor scripts to be made on the prefab
            // (These are generally for game-specific needs)
            CustomizePrefab(tempPrefab, customImporters);

            // Part 3.5: Apply the scale only after all children have been added
            tempPrefab.transform.localScale = new Vector3(prefabScale, prefabScale, prefabScale);

            // Part 4: Save the prefab, keeping references intact.
            string resourcePath = ImportUtils.GetAttributeAsString(xmlPrefab, "resourcePath", "");
            bool   isResource   = !String.IsNullOrEmpty(resourcePath) || ImportUtils.GetAttributeAsBoolean(xmlPrefab, "resource", false);
            string prefabPath   = GetPrefabAssetPath(prefabName, isResource, resourcePath);
            string prefabFile   = Path.GetFileName(prefabPath);

            // Keep track of the prefab file being imported
            if (!importComponent.ImportWait_Prefabs.Contains(prefabFile, StringComparer.OrdinalIgnoreCase))
            {
                importComponent.ImportWait_Prefabs.Add(prefabFile);
                importComponent.ImportingAssets.Add(prefabPath);
            }

            UnityEngine.Object finalPrefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));

            if (finalPrefab == null)
            {
                // The prefab needs to be created
                ImportUtils.ReadyToWrite(prefabPath);
                finalPrefab = PrefabUtility.CreateEmptyPrefab(prefabPath);
            }

            // Replace the prefab, keeping connections based on name. This imports the prefab asset as a side-effect.
            PrefabUtility.ReplacePrefab(tempPrefab, finalPrefab, ReplacePrefabOptions.ReplaceNameBased);

            // Destroy the instance from the current scene hiearchy.
            UnityEngine.Object.DestroyImmediate(tempPrefab);
        }
示例#2
0
        private void CreatePrefab(XElement xmlPrefab, string objPath)
        {
            var customImporters = GetCustomImporterInstances();

            // Part 1: Create the prefab
            string     prefabName  = xmlPrefab.Attribute("name").Value;
            float      prefabScale = ImportUtils.GetAttributeAsFloat(xmlPrefab, "scale", 1.0f);
            GameObject tempPrefab  = new GameObject(prefabName);

            // Part 2: Build out the prefab
            // We may have an 'isTrigger' attribute that we want our children to obey
            bool isTrigger = ImportUtils.GetAttributeAsBoolean(xmlPrefab, "isTrigger", false);

            AddGameObjectsTo(tempPrefab, xmlPrefab, isTrigger, objPath, customImporters);

            // Part 3: Allow for customization from other editor scripts to be made on the prefab
            // (These are generally for game-specific needs)
            CustomizePrefab(tempPrefab, customImporters);

            // Part 3.5: Apply the scale only after all children have been added
            tempPrefab.transform.localScale = new Vector3(prefabScale, prefabScale, prefabScale);

            // Part 4: Save the prefab, keeping references intact.
            string resourcePath = ImportUtils.GetAttributeAsString(xmlPrefab, "resourcePath", "");
            bool   isResource   = !String.IsNullOrEmpty(resourcePath) || ImportUtils.GetAttributeAsBoolean(xmlPrefab, "resource", false);
            string prefabPath   = GetPrefabAssetPath(prefabName, isResource, resourcePath);

            UnityEngine.Object finalPrefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));

            //Part 5:  Handle properities (uses info regarding whether or not the prefab was already defined)
            int previousMapId = 0;
            MetadataSettings previousMetadata = null;

            if (finalPrefab != null)
            {
                TiledMap map = ((GameObject)AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject))).GetComponent <TiledMap>();
                previousMapId    = map.MapID;
                previousMetadata = ((GameObject)AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject))).GetComponent <MetadataSettings>();
            }
            HandleTiledAttributes(tempPrefab, xmlPrefab, previousMapId, previousMetadata);
            HandleCustomProperties(tempPrefab, xmlPrefab, customImporters);

            if (finalPrefab == null)
            {
                // The prefab needs to be created
                ImportUtils.ReadyToWrite(prefabPath);
                finalPrefab = PrefabUtility.CreateEmptyPrefab(prefabPath);
            }

            // Replace the prefab, keeping connections based on name.
            PrefabUtility.ReplacePrefab(tempPrefab, finalPrefab, ReplacePrefabOptions.ReplaceNameBased);

            // Destroy the instance from the current scene hiearchy.
            UnityEngine.Object.DestroyImmediate(tempPrefab);
        }
示例#3
0
        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;
                }

                float x = ImportUtils.GetAttributeAsFloat(goXml, "x", 0);
                float y = ImportUtils.GetAttributeAsFloat(goXml, "y", 0);
                child.transform.position = new Vector3(x, y, 0);

                // 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 UnityEngine.Material CreateMaterialFromXml(XElement xml, Tiled2Unity.ImportBehaviour importComponent)
        {
            // Does this material support alpha color key?
            bool useColorKey     = xml.Attribute("alphaColorKey") != null;
            bool usesDepthShader = ImportUtils.GetAttributeAsBoolean(xml, "usesDepthShaders", false);

            // Determine which shader we sould be using
            string shaderName = "Tiled2Unity/";

            // Are we using depth shaders?
            if (usesDepthShader)
            {
                shaderName += "Depth";
            }
            else
            {
                shaderName += "Default";
            }

            // Are we using color key shaders?
            Color keyColor = Color.black;

            if (useColorKey)
            {
                keyColor    = ImportUtils.GetAttributeAsColor(xml, "alphaColorKey");
                shaderName += " Color Key";
            }

            // Try creating the material with the right shader. Fall back to the built-in Sprites/Default shader if there's a problem.
            UnityEngine.Material material = null;
            try
            {
                material = new UnityEngine.Material(UnityEngine.Shader.Find(shaderName));
            }
            catch (Exception e)
            {
                importComponent.RecordError("Error creating material with shader '{0}'. {1}", shaderName, e.Message);
            }

            if (material == null)
            {
                importComponent.RecordWarning("Using default sprite shader for material");
                material = new UnityEngine.Material(UnityEngine.Shader.Find("Sprites/Default"));
            }

            if (useColorKey)
            {
                material.SetColor("_AlphaColorKey", keyColor);
            }

            return(material);
        }
示例#5
0
        private void AddTileObjectComponentsTo(GameObject gameObject, XElement goXml)
        {
            var tileXml = goXml.Element("TileObjectComponent");

            if (tileXml != null)
            {
                TileObject tileObject = gameObject.AddComponent <TileObject>();
                FillBaseTmxObjectProperties(tileObject, tileXml);
                tileObject.TmxFlippingHorizontal = ImportUtils.GetAttributeAsBoolean(tileXml, "tmx-tile-flip-horizontal", false);
                tileObject.TmxFlippingVertical   = ImportUtils.GetAttributeAsBoolean(tileXml, "tmx-tile-flip-vertical", false);
                tileObject.TileWidth             = ImportUtils.GetAttributeAsFloat(tileXml, "width");
                tileObject.TileHeight            = ImportUtils.GetAttributeAsFloat(tileXml, "height");
            }
        }
        private void CreatePrefab(XElement xmlPrefab, string objPath)
        {
            var customImporters = GetCustomImporterInstances();

            // Part 1: Create the prefab
            string     prefabName  = xmlPrefab.Attribute("name").Value;
            float      prefabScale = ImportUtils.GetAttributeAsFloat(xmlPrefab, "scale", 1.0f);
            GameObject tempPrefab  = new GameObject(prefabName);

            tempPrefab.AddComponent <LevelInfo>();
            HandleTiledAttributes(tempPrefab, xmlPrefab);
            HandleCustomProperties(tempPrefab, xmlPrefab, customImporters);

            // Part 2: Build out the prefab
            // We may have an 'isTrigger' attribute that we want our children to obey
            bool isTrigger = ImportUtils.GetAttributeAsBoolean(xmlPrefab, "isTrigger", false);

            AddGameObjectsTo(tempPrefab, xmlPrefab, isTrigger, objPath, customImporters);

            // Part 3: Allow for customization from other editor scripts to be made on the prefab
            // (These are generally for game-specific needs)
            CustomizePrefab(tempPrefab, customImporters);

            // Part 3.5: Apply the scale only after all children have been added
            tempPrefab.transform.localScale = new Vector3(prefabScale, prefabScale, prefabScale);

            // Part 4: Save the prefab, keeping references intact.
            // Modified By:
            // Kurtis Thiessen - June 2

            // Save into levels
            string prefabPath = String.Format("Assets/Resources/Levels/{0}.prefab", prefabName);

            //string prefabPath = ImportUtils.GetPrefabPathFromName(prefabName);

            UnityEngine.Object finalPrefab = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));

            if (finalPrefab == null)
            {
                // The prefab needs to be created
                ImportUtils.ReadyToWrite(prefabPath);
                finalPrefab = PrefabUtility.CreateEmptyPrefab(prefabPath);
            }

            // Replace the prefab, keeping connections based on name.
            PrefabUtility.ReplacePrefab(tempPrefab, finalPrefab, ReplacePrefabOptions.ReplaceNameBased);

            // Destroy the instance from the current scene hiearchy.
            UnityEngine.Object.DestroyImmediate(tempPrefab);
        }
        private UnityEngine.Material CreateMaterialFromXml(XElement xml)
        {
            // Does this material support alpha color key?
            string htmlColor       = ImportUtils.GetAttributeAsString(xml, "alphaColorKey", "");
            bool   usesDepthShader = ImportUtils.GetAttributeAsBoolean(xml, "usesDepthShaders", false);

            // Determine which shader we sould be using
            string shaderName = "Tiled2Unity/";

            // Are we using depth shaders?
            if (usesDepthShader)
            {
                shaderName += "Depth";
            }
            else
            {
                shaderName += "Default";
            }

            // Are we using color key shaders?
            Color?keyColor = null;

            if (!String.IsNullOrEmpty(htmlColor))
            {
                shaderName += " Color Key";

                // Sometimes Tiled saves out color without the leading # but we expect it to be there
                if (!htmlColor.StartsWith("#"))
                {
                    htmlColor = "#" + htmlColor;
                }

                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);
                keyColor = new Color32(r, g, b, 255);
            }

            UnityEngine.Material material = new UnityEngine.Material(UnityEngine.Shader.Find(shaderName));

            if (keyColor.HasValue)
            {
                material.SetColor("_AlphaColorKey", keyColor.Value);
            }

            return(material);
        }
示例#8
0
        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);
            }
        }
        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;
            }
        }
示例#10
0
        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 = Path.GetFileName(materialPath);

                // Keep track that we importing this material
                importComponent.ImportWait_Materials.Add(materialFile);

                // Create the material
                UnityEngine.Material material = CreateMaterialFromXml(xmlTexture);

                // Assign the texture to the material
                {
                    string    textureAsset = GetTextureAssetPath(textureFile);
                    Texture2D texture2d    = AssetDatabase.LoadAssetAtPath(textureAsset, typeof(Texture2D)) as Texture2D;
                    material.SetTexture("_MainTex", texture2d);
                }

                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  = Path.GetFileName(textureAsset);
                string materialPath = MakeMaterialAssetPath(textureFile, isResource);
                string materialFile = Path.GetFileName(materialPath);

                // Keep track that we importing this material
                importComponent.ImportWait_Materials.Add(materialFile);

                // Create the material
                UnityEngine.Material material = CreateMaterialFromXml(xmlInternal);

                // Assign the texture to the material
                {
                    Texture2D texture2d = AssetDatabase.LoadAssetAtPath(textureAsset, typeof(Texture2D)) as Texture2D;
                    material.SetTexture("_MainTex", texture2d);
                }

                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, string objPath, IList <ICustomTiledImporter> customImporters)
        {
            foreach (XElement goXml in xml.Elements("GameObject"))
            {
                string name = ImportUtils.GetAttributeAsString(goXml, "name", "");

                // The normal map layer does not need to be included in the mesh. It is only used so that the texture gets imported from tiled to Unity by Tiled2Unity tool
                if (name.Contains(ImportTiled2Unity.TiledGameObjectName_NormalMapLayer))
                {
                    continue;
                }

                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, 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 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);
                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 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);
            }
        }