private static bool UseThisImporter(string assetPath)
        {
#if UNITY_WEBPLAYER
            String warning = String.Format("Can not import through Tiled2Unity using the WebPlayer platform. This is depecrated by Unity Technologies and is no longer supported. Go to File -> Build Settings... and switch to another platform. (You can switch back to Web Player after importing.). File: {0}", assetPath);
            Debug.LogError(warning);
            return(false);
#else
            // Certain file types are ignored by this asset post processor (i.e. scripts)
            // (Note that an empty string as the extension is a folder)
            string[] ignoreThese = { ".cs", ".txt", ".shader", "", };
            if (ignoreThese.Any(ext => String.Compare(ext, System.IO.Path.GetExtension(assetPath), true) == 0))
            {
                return(false);
            }

            // *.tiled2unity.xml files are always supported by this processor
            if (assetPath.EndsWith(".tiled2unity.xml", StringComparison.InvariantCultureIgnoreCase))
            {
                return(true);
            }

            // All other files can only use this post processor if their import was requested by an ImportBehaviour
            return(ImportBehaviour.IsAssetBeingImportedByTiled2Unity(assetPath));
#endif
        }
Beispiel #2
0
        // We have many independent requests on the ImportBehaviour so we can't take for granted it has been created yet.
        // However, if it has been created then use it.
        public static ImportBehaviour FindOrCreateImportBehaviour(string xmlPath)
        {
            string importName = ImportBehaviour.GetFilenameWithoutTiled2UnityExtension(xmlPath);

            // Try to find
            foreach (ImportBehaviour status in UnityEngine.Object.FindObjectsOfType <ImportBehaviour>())
            {
                if (String.Compare(status.ImportName, importName, true) == 0)
                {
                    return(status);
                }
            }

            // Couldn't find, so create.
            GameObject gameObject = new GameObject("__temp_tiled2unity_import");

#if !UNITY_4_0 && !UNITY_4_0_1 && !UNITY_4_2 && !UNITY_4_3
            gameObject.transform.SetAsFirstSibling();
#endif

            ImportBehaviour importStatus = gameObject.AddComponent <ImportBehaviour>();
            importStatus.ImportName = importName;

            // Opening the XDocument itself can be expensive so start the progress bar just before we start
            importStatus.StartProgressBar(xmlPath);
            importStatus.XmlDocument = XDocument.Load(xmlPath);

            importStatus.numberOfElements = importStatus.XmlDocument.Element("Tiled2Unity").Elements().Count();
            importStatus.IncrementProgressBar(xmlPath);

            return(importStatus);
        }
Beispiel #3
0
        private GameObject CreateGameObjectWithMesh(string meshName, ImportBehaviour importComponent)
        {
            string meshAssetPath = GetMeshAssetPath(importComponent.MapName, meshName);

            UnityEngine.Object[] objects = AssetDatabase.LoadAllAssetsAtPath(meshAssetPath);

            foreach (var obj in objects)
            {
                // Do we have a game object?
                GameObject gameObj = obj as GameObject;

                if (gameObj == null)
                {
                    continue;
                }

                // Does the game object have a MeshRenderer component?
                if (gameObj.GetComponent <MeshRenderer>() != null)
                {
                    GameObject instancedGameObj = GameObject.Instantiate(gameObj) as GameObject;
                    instancedGameObj.AddComponent <SortingLayerExposed>();
                    return(instancedGameObj);
                }
            }

            // If we're here then there's an error
            importComponent.RecordError("No mesh named '{0}' to create game object from.\nXml File: {1}\nObject: {2}", meshName, importComponent.Tiled2UnityXmlPath, meshAssetPath);
            return(null);
        }
Beispiel #4
0
        private void AssignSortingLayerNameTo(GameObject gameObject, XElement xml, ImportBehaviour importComponent)
        {
            string sortingLayer = ImportUtils.GetAttributeAsString(xml, "sortingLayerName", "");

            if (String.IsNullOrEmpty(sortingLayer))
            {
                return;
            }

            Renderer renderer = gameObject.GetComponent <Renderer>();

            if (renderer == null)
            {
                importComponent.RecordWarning("Sorting Layer '{0}' cannot be assigned on '{1}' without a RendererComponent", sortingLayer, gameObject.name);
                return;
            }

            if (!SortingLayerExposedEditor.GetSortingLayerNames().Contains(sortingLayer))
            {
                importComponent.RecordError("Sorting Layer \"{0}\" does not exist. Check your Project Settings -> Tags and Layers", sortingLayer);
                renderer.sortingLayerName = "Default";
            }

            renderer.sortingLayerName = sortingLayer;
        }
Beispiel #5
0
        private GameObject CreateCopyFromMeshObj(string copyFromName, ImportBehaviour importComponent)
        {
            importComponent.RecordWarning("Deprecated import action. Re-export map '{0}' with newer version of Tiled2Unity.", importComponent.MapName);

            // Find a matching game object within the mesh object and "copy" it
            // (In Unity terms, the Instantiated object is a copy)
            string objPath = GetMeshAssetPath(importComponent.MapName, importComponent.MapName);

            UnityEngine.Object[] objects = AssetDatabase.LoadAllAssetsAtPath(objPath);

            foreach (var obj in objects)
            {
                if (obj.name != copyFromName)
                {
                    continue;
                }

                // We have a match but is it a game object?
                GameObject gameObj = GameObject.Instantiate(obj) as GameObject;

                if (gameObj == null)
                {
                    continue;
                }

                // Reset the name so it is not decorated by the Instantiate call
                gameObj.name = obj.name;
                return(gameObj);
            }

            // If we're here then there's an error with the mesh name
            importComponent.RecordError("No mesh named '{0}' to copy from.\nXml File: {1}\nObject: {2}", copyFromName, importComponent.Tiled2UnityXmlPath, objPath);
            return(null);
        }
Beispiel #6
0
        private IList <ICustomTiledImporter> GetCustomImporterInstances(ImportBehaviour importComponent)
        {
            // Report an error for ICustomTiledImporter classes that don't have the CustomTiledImporterAttribute
            var errorTypes = from a in AppDomain.CurrentDomain.GetAssemblies()
                             from t in a.GetTypes()
                             where typeof(ICustomTiledImporter).IsAssignableFrom(t)
                             where !t.IsAbstract
                             where System.Attribute.GetCustomAttribute(t, typeof(CustomTiledImporterAttribute)) == null
                             select t;

            foreach (var t in errorTypes)
            {
                importComponent.RecordError("ICustomTiledImporter type '{0}' is missing CustomTiledImporterAttribute", t);
            }

            // Find all the types with the CustomTiledImporterAttribute, instantiate them, and give them a chance to customize our prefab
            var types = from a in AppDomain.CurrentDomain.GetAssemblies()
                        from t in a.GetTypes()
                        where typeof(ICustomTiledImporter).IsAssignableFrom(t)
                        where !t.IsAbstract
                        from attr in System.Attribute.GetCustomAttributes(t, typeof(CustomTiledImporterAttribute))
                        let custom = attr as CustomTiledImporterAttribute
                                     orderby custom.Order
                                     select t;

            var instances = types.Select(t => (ICustomTiledImporter)Activator.CreateInstance(t));

            return(instances.ToList());
        }
        private GameObject CreateGameObjectWithMesh(string meshName, ImportBehaviour importComponent)
        {
            string     meshAssetPath  = GetMeshAssetPath(importComponent.MapName, Path.GetFileNameWithoutExtension(meshName));
            GameObject meshGameObject = AssetDatabase.LoadAssetAtPath(meshAssetPath, typeof(GameObject)) as GameObject;

            if (meshGameObject == null)
            {
                importComponent.RecordError("Mesh object not imported: {0}", meshAssetPath);
                return(null);
            }

            MeshRenderer meshRenderer = meshGameObject.GetComponentInChildren <MeshRenderer>();

            if (meshRenderer == null)
            {
                importComponent.RecordError("Imported mesh object missing renderer: {0}", meshAssetPath);
                return(null);
            }

            // Create an instance of our mesh game object
            GameObject instancedGameObj = GameObject.Instantiate(meshRenderer.gameObject) as GameObject;

            instancedGameObj.AddComponent <SortingLayerExposed>();
            return(instancedGameObj);
        }
Beispiel #8
0
        // Called when the import process has completed and we have a prefab ready to go
        public void ImportFinished(string prefabPath)
        {
            // Get at the import behavour tied to this prefab and remove it from the scene
            string          xmlAssetPath    = GetXmlImportAssetPath(prefabPath);
            ImportBehaviour importBehaviour = ImportBehaviour.FindOrCreateImportBehaviour(xmlAssetPath);

            importBehaviour.DestroyImportBehaviour();
        }
        // We need to call this while the renderers on the model is having its material assigned to it
        // This is invoked for every submesh in the .obj wavefront mesh
        public Material FixMaterialForMeshRenderer(string objName, Renderer renderer)
        {
            string          xmlPath        = GetXmlImportAssetPath(objName);
            ImportBehaviour importBehavior = ImportBehaviour.FindOrCreateImportBehaviour(xmlPath);

            // The mesh to match
            string meshName = renderer.name;

            // Increment our progress bar
            importBehavior.IncrementProgressBar(String.Format("Assign material: {0}", meshName));

            // Find an assignment that matches the mesh renderer
            var      assignMaterials = importBehavior.XmlDocument.Root.Elements("AssignMaterial");
            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 + ".mat";
            string materialPath = GetMaterialAssetPath(materialName);

            // Assign the material
            Material material = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material;

            if (material == null)
            {
                Debug.LogError(String.Format("Could not find material: {0}", materialName));
            }

            // 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);
                material.SetColor("_AlphaColorKey", color);
            }

            return(material);
        }
        // Called when the import process has completed and we have a prefab ready to go
        public void ImportFinished(string prefabPath)
        {
            // String the prefab extension
            string prefabName = Path.GetFileNameWithoutExtension(prefabPath);

            // Get at the import behavour tied to this prefab and remove it from the scene
            string          xmlAssetPath    = GetXmlImportAssetPath(prefabName);
            ImportBehaviour importBehaviour = ImportBehaviour.FindOrCreateImportBehaviour(xmlAssetPath);

            importBehaviour.DestroyImportBehaviour();
        }
        // By the time this is called, our assets should be ready to create the map prefab
        public void MeshImported(string objPath)
        {
            string xmlPath = GetXmlImportAssetPath(objPath);

            ImportBehaviour importBehaviour = ImportBehaviour.FindOrCreateImportBehaviour(xmlPath);

            importBehaviour.IncrementProgressBar(String.Format("Create prefab: {0}", Path.GetFileNameWithoutExtension(GetPrefabAssetPath(objPath, false, null))));

            foreach (var xmlPrefab in importBehaviour.XmlDocument.Root.Elements("Prefab"))
            {
                CreatePrefab(xmlPrefab, objPath);
            }
        }
Beispiel #12
0
        private void AssignOpacityTo(GameObject gameObject, XElement xml, ImportBehaviour importComponent)
        {
            float opacity = ImportUtils.GetAttributeAsFloat(xml, "opacity", 1.0f);

            if (opacity == 1.0f)
            {
                return;
            }

#if UNITY_5_6_OR_NEWER
            // Add a component that will control our instanced shader properties
            Tiled2Unity.GPUInstancing instancing = gameObject.GetOrAddComponent <Tiled2Unity.GPUInstancing>();
            instancing.Opacity = opacity;
#endif
        }
        // By the time this is called, our assets should be ready to create the map prefab
        public void MeshImported(string objPath)
        {
            // String the mesh type (.obj) from the path
            string objName = Path.GetFileNameWithoutExtension(objPath);

            // Get the XML file that this mesh came from
            string xmlPath = GetXmlImportAssetPath(objName);

            ImportBehaviour importBehaviour = ImportBehaviour.FindOrCreateImportBehaviour(xmlPath);

            importBehaviour.IncrementProgressBar(String.Format("Create prefab: {0}", Path.GetFileNameWithoutExtension(GetPrefabAssetPath(objName, false, null))));

            foreach (var xmlPrefab in importBehaviour.XmlDocument.Root.Elements("Prefab"))
            {
                CreatePrefab(xmlPrefab, objPath);
            }
        }
Beispiel #14
0
        private void AssignSortingOrderTo(GameObject gameObject, XElement xml, ImportBehaviour importComponent)
        {
            if (xml.Attribute("sortingOrder") == null)
            {
                return;
            }

            int sortingOrder = ImportUtils.GetAttributeAsInt(xml, "sortingOrder");

            Renderer renderer = gameObject.GetComponent <Renderer>();

            if (renderer == null)
            {
                importComponent.RecordWarning("Sorting Order '{0}' cannot be assigned on '{1}' without a RendererComponent", sortingOrder, gameObject.name);
                return;
            }

            renderer.sortingOrder = sortingOrder;
        }
Beispiel #15
0
        private void AssignTagTo(GameObject gameObject, XElement xml, ImportBehaviour importComponent)
        {
            string tag = ImportUtils.GetAttributeAsString(xml, "tag", "");

            if (String.IsNullOrEmpty(tag))
            {
                return;
            }

            // Let the user know if the tag doesn't exist in our project settings
            try
            {
                gameObject.tag = tag;
            }
            catch (UnityException)
            {
                importComponent.RecordError("Tag '{0}' is not defined for '{1}'. Check project settings in Edit->Project Settings->Tags & Layers", tag, GetFullGameObjectName(gameObject.transform));
            }
        }
        // We need to call this while the renderers on the model is having its material assigned to it
        // This is invoked for every submesh in the .obj wavefront mesh
        public Material FixMaterialForMeshRenderer(string objName, Renderer renderer)
        {
            string          xmlPath        = GetXmlImportAssetPath(objName);
            ImportBehaviour importBehavior = ImportBehaviour.FindOrCreateImportBehaviour(xmlPath);

            // The mesh to match
            string meshName = renderer.name;

            // Increment our progress bar
            importBehavior.IncrementProgressBar(String.Format("Assign material: {0}", meshName));

            // Find an assignment that matches the mesh renderer
            var      assignMaterials = importBehavior.XmlDocument.Root.Elements("AssignMaterial");
            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 + ".mat";
            string materialPath = GetMaterialAssetPath(materialName);

            // Assign the material
            Material material = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material;

            if (material == null)
            {
                Debug.LogError(String.Format("Could not find material: {0}", materialName));
            }

            return(material);
        }
Beispiel #17
0
        // Called when Unity detects the *.tiled2unity.xml file needs to be (re)imported
        public void ImportBegin(string xmlPath)
        {
            // Normally, this is where we first create the XmlDocument for the whole import.
            ImportBehaviour importBehaviour = ImportBehaviour.FindOrCreateImportBehaviour(xmlPath);
            XDocument       xml             = importBehaviour.XmlDocument;

            if (xml == null)
            {
                Debug.LogError(String.Format("GameObject {0} not successfully initialized. Is it left over from a previous import. Try removing from scene are re-importing {1}.", importBehaviour.gameObject.name, xmlPath));
                return;
            }

            CheckVersion(xmlPath, xml);

            // Import asset files.
            // (Note that textures should be imported before meshes)
            ImportTexturesFromXml(xml);
            CreateMaterialsFromInternalTextures(xml);
            ImportMeshesFromXml(xml);
        }
Beispiel #18
0
        private void AssignLayerTo(GameObject gameObject, XElement xml, ImportBehaviour importComponent)
        {
            string layerName = ImportUtils.GetAttributeAsString(xml, "layer", "");

            if (String.IsNullOrEmpty(layerName))
            {
                return;
            }

            int layerId = LayerMask.NameToLayer(layerName);

            if (layerId == -1)
            {
                importComponent.RecordError("Layer '{0}' is not defined for '{1}'. Check project settings in Edit->Project Settings->Tags & Layers", layerName, GetFullGameObjectName(gameObject.transform));
                return;
            }

            // Set the layer on ourselves (and our children)
            AssignLayerIdTo(gameObject, layerId);
        }
Beispiel #19
0
        public void TextureImported(string texturePath)
        {
            // Find the import behaviour that was waiting on this texture to be imported
            string asset = System.IO.Path.GetFileName(texturePath);

            foreach (var importComponent in ImportBehaviour.EnumerateImportBehaviors_ByWaitingTexture(asset))
            {
                // The texture has finished loading. Keep track of that status.
                if (!importComponent.ImportComplete_Textures.Contains(asset, StringComparer.OrdinalIgnoreCase))
                {
                    importComponent.ImportComplete_Textures.Add(asset);
                }

                // Are we done importing all textures? If so then start importing materials.
                if (importComponent.IsTextureImportingCompleted())
                {
                    ImportAllMaterials(importComponent);
                }
            }
        }
Beispiel #20
0
        public void MaterialImported(string materialPath)
        {
            // Find the import behaviour that was waiting on this material to be imported
            string asset = Path.GetFileName(materialPath);

            foreach (var importComponent in ImportBehaviour.EnumerateImportBehaviors_ByWaitingMaterial(asset))
            {
                // The material has finished loading. Keep track of that status.
                if (!importComponent.ImportComplete_Materials.Contains(asset))
                {
                    importComponent.ImportComplete_Materials.Add(asset);
                }

                // Are we done importing all materials? If so then start importing meshes.
                if (importComponent.IsMaterialImportingCompleted())
                {
                    ImportAllMeshes(importComponent);
                }
            }
        }
        public void MeshImported(string objPath)
        {
            // Find the import behaviour that was waiting on this mesh to be imported
            string          asset           = System.IO.Path.GetFileName(objPath);
            ImportBehaviour importComponent = ImportBehaviour.FindImportBehavior_ByWaitingMesh(asset);

            if (importComponent != null)
            {
                // The mesh has finished loading. Keep track of that status.
                if (!importComponent.ImportComplete_Meshes.Contains(asset))
                {
                    importComponent.ImportComplete_Meshes.Add(asset);
                }

                // Are we done importing all meshes? If so then start importing prefabs.
                if (importComponent.IsMeshImportingCompleted())
                {
                    ImportAllPrefabs(importComponent, objPath);
                }
            }
        }
Beispiel #22
0
        private bool LoadTiled2UnityXml(ImportBehaviour importComponent, string xmlPath)
        {
            try
            {
                var xml = XDocument.Load(xmlPath);
                importComponent.XmlDocument = xml;

                var xmlTiled2Unity = xml.Element("Tiled2Unity");
                importComponent.Tiled2UnityXmlPath         = xmlPath;
                importComponent.ExporterTiled2UnityVersion = ImportUtils.GetAttributeAsString(xmlTiled2Unity, "version");
                return(true);
            }
            catch (Exception e)
            {
                string msg = String.Format("Error importing Tiled2Unity xml file '{0}': {1}", xmlPath, e.Message);
                Debug.LogError(msg);
                importComponent.DestroyImportBehaviour();
            }

            return(false);
        }
        // We need to call this while the renderers on the model is having its material assigned to it
        // This is invoked for every submesh in the .obj wavefront mesh
        public UnityEngine.Material FixMaterialForMeshRenderer(string objName, Renderer renderer)
        {
            // Find the import behaviour that is waiting for the mesh to be imported.
            string          assetName      = objName + ".obj";
            ImportBehaviour importBehavior = ImportBehaviour.FindImportBehavior_ByWaitingMesh(assetName);

            // The mesh to match
            string meshName = renderer.name;

            // Find an assignment that matches the mesh renderer
            var      assignMaterials = importBehavior.XmlDocument.Root.Elements("AssignMaterial");
            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);

                importBehavior.RecordError(builder.ToString());
                return(null);
            }

            string materialName = match.Attribute("material").Value + ".mat";
            string materialPath = GetExistingMaterialAssetPath(materialName);

            // Assign the material
            UnityEngine.Material material = AssetDatabase.LoadAssetAtPath(materialPath, typeof(UnityEngine.Material)) as UnityEngine.Material;
            if (material == null)
            {
                importBehavior.RecordError("Could not find material: {0}", materialName);
            }

            return(material);
        }
Beispiel #24
0
        public void PrefabImported(string prefabPath)
        {
            // Find the import behaviour that was waiting on this prefab to be imported
            string          asset           = Path.GetFileName(prefabPath);
            ImportBehaviour importComponent = ImportBehaviour.FindImportBehavior_ByWaitingPrefab(asset);

            if (importComponent != null)
            {
                // The prefab has finished loading. Keep track of that status.
                if (!importComponent.ImportComplete_Prefabs.Contains(asset, StringComparer.OrdinalIgnoreCase))
                {
                    importComponent.ImportComplete_Prefabs.Add(asset);
                }

                // Are we done importing all Prefabs? If so then we have completed the import process.
                if (importComponent.IsPrefabImportingCompleted())
                {
                    importComponent.ReportPrefabImport(prefabPath);
                    importComponent.DestroyImportBehaviour();
                }
            }
        }
        public void PrefabImported(string prefabPath)
        {
            // Find the import behaviour that was waiting on this prefab to be imported
            string          asset           = Path.GetFileName(prefabPath);
            ImportBehaviour importComponent = ImportBehaviour.FindImportBehavior_ByWaitingPrefab(asset);

            if (importComponent != null)
            {
                // The prefab has finished loading. Keep track of that status.
                if (!importComponent.ImportComplete_Prefabs.Contains(asset))
                {
                    importComponent.ImportComplete_Prefabs.Add(asset);
                }

                // Are we done importing all Prefabs? If so then we have completed the import process.
                if (importComponent.IsPrefabImportingCompleted())
                {
                    string msg = String.Format("Succefully imported prefab '{0}' from '{1}'", prefabPath, importComponent.Tiled2UnityXmlPath);
                    Debug.Log(msg);
                    importComponent.DestroyImportBehaviour();
                }
            }
        }
        private void AssignTextureAssetToMaterial(Material material, string materialFile, string textureAsset, ImportBehaviour importComponent)
        {
            Texture2D texture2d = AssetDatabase.LoadAssetAtPath(textureAsset, typeof(Texture2D)) as Texture2D;

            if (texture2d == null)
            {
                importComponent.RecordError("Error creating material '{0}'. Texture was not found: {1}", materialFile, textureAsset);
            }
            material.SetTexture("_MainTex", texture2d);
        }
Beispiel #27
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, ImportBehaviour importComponent, 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, importComponent);
                    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))
                    {
                        importComponent.RecordError("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);
                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 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, importComponent, customImporters);

                // Does this game object have a tag?
                AssignTagTo(child, goXml, importComponent);

                // Does this game object have a layer?
                AssignLayerTo(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 GameObject CreateCopyFromMeshObj(string copyFromName, string objPath, float opacity, ImportBehaviour importComponent)
        {
            // Find a matching game object within the mesh object and "copy" it
            // (In Unity terms, the Instantiated object is a copy)
            UnityEngine.Object[] objects = AssetDatabase.LoadAllAssetsAtPath(objPath);
            foreach (var obj in objects)
            {
                if (obj.name != copyFromName)
                {
                    continue;
                }

                // We have a match but is it a game object?
                GameObject gameObj = GameObject.Instantiate(obj) as GameObject;
                if (gameObj == null)
                {
                    continue;
                }

                // Add a component that will control our initial shader properties
                TiledInitialShaderProperties shaderProps = gameObj.AddComponent <TiledInitialShaderProperties>();
                shaderProps.InitialOpacity = opacity;

                // Reset the name so it is not decorated by the Instantiate call
                gameObj.name = obj.name;
                return(gameObj);
            }

            // If we're here then there's an error with the mesh name
            importComponent.RecordError("No mesh named '{0}' to copy from.\nXml File: {1}\nObject: {2}", copyFromName, importComponent.Tiled2UnityXmlPath, objPath);
            return(null);
        }