private void AddTileAnimatorsTo(GameObject gameObject, XElement goXml) { // This object will only visible for a given moment of time within an animation var animXml = goXml.Element("TileAnimator"); if (animXml != null) { TileAnimator tileAnimator = gameObject.AddComponent <TileAnimator>(); tileAnimator.StartTime = ImportUtils.GetAttributeAsInt(animXml, "startTimeMs") * 0.001f; tileAnimator.Duration = ImportUtils.GetAttributeAsInt(animXml, "durationMs") * 0.001f; tileAnimator.TotalAnimationTime = ImportUtils.GetAttributeAsInt(animXml, "fullTimeMs") * 0.001f; } }
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"); } }
// Modified By: // Kurtis Thiessen - June 2 private void AddWeatherScriptsTo(GameObject gameObject, XElement goXml) { foreach (var animXml in goXml.Elements("TileAnimator")) { WeatherTile weatherTile = gameObject.AddComponent <WeatherTile>(); foreach (var frameXml in animXml.Elements("Frame")) { WeatherTile.Frame tileFrame = new WeatherTile.Frame(); tileFrame.Vertex_z = ImportUtils.GetAttributeAsFloat(frameXml, "vertex_z"); weatherTile.frames.Add(tileFrame); } } }
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); }
public void HandleCustomProperties(UnityEngine.GameObject gameObject, IDictionary <string, string> props) { // Add a terrain type to our game object if (props.ContainsKey("terrainType")) { TerrainType terrainType = (TerrainType)ImportUtils.GetAttributeAsEnum(props["terrainType"], typeof(TerrainType)); if (terrainType != null) { gameObject.AddComponent <TerrainTagChecker>(); gameObject.GetComponent <TerrainTagChecker>().curTerrainType = terrainType; } } }
private void CreateMaterialsFromInternalTextures(XDocument xml) { var texData = xml.Root.Elements("InternalTexture"); foreach (var tex in texData) { string texAssetPath = tex.Attribute("assetPath").Value; // Check to see if normal map processing is necessary and if this is a normal map file. At this stage we only want to load just plain textures which are not normal maps if (ImportTiled2Unity.ProcessingNormalMaps && texAssetPath.Contains(ImportTiled2Unity.TiledNormalMapFileIdentification)) { continue; } string materialPath = GetMaterialAssetPath(texAssetPath); Material material = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material; if (material == null) { // Create our material if (ImportTiled2Unity.ProcessingNormalMaps) { material = new Material(Shader.Find("Tiled/TextureTintSnapNormal")); } else { material = new Material(Shader.Find("Tiled/TextureTintSnap")); } // Assign to it the texture that is already internal to our Unity project Texture2D texture2d = AssetDatabase.LoadAssetAtPath(texAssetPath, typeof(Texture2D)) as Texture2D; material.SetTexture("_MainTex", texture2d); // Now the normal map file should be searched and loaded AND assigned to the material for shader processing. if (ImportTiled2Unity.ProcessingNormalMaps) { var normalMapAssetPath = texData.SingleOrDefault(o => tex.Attribute("assetPath").Value.Contains(ImportTiled2Unity.TiledNormalMapFileIdentification)); if (normalMapAssetPath != null) { Texture2D texture2dNormal = AssetDatabase.LoadAssetAtPath(normalMapAssetPath.Value, typeof(Texture2D)) as Texture2D; material.SetTexture("_BumpMap", texture2dNormal); } } // Write the material to our asset database ImportUtils.ReadyToWrite(materialPath); AssetDatabase.CreateAsset(material, materialPath); } } }
private void AddTileAnimatorsTo(GameObject gameObject, XElement goXml) { foreach (var animXml in goXml.Elements("TileAnimator")) { TileAnimator tileAnimator = gameObject.AddComponent <TileAnimator>(); foreach (var frameXml in animXml.Elements("Frame")) { TileAnimator.Frame frame = new TileAnimator.Frame(); frame.Vertex_z = ImportUtils.GetAttributeAsFloat(frameXml, "vertex_z"); frame.DurationMs = ImportUtils.GetAttributeAsInt(frameXml, "duration"); tileAnimator.frames.Add(frame); } } }
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 }
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); }
private void OnPostprocessModel(GameObject gameObject) { if (!UseThisImporter()) { return; } // Each mesh renderer has the ability to set the a sort layer but it takes some work with Unity to expose it. foreach (MeshRenderer mr in gameObject.GetComponentsInChildren <MeshRenderer>()) { mr.gameObject.AddComponent <SortingLayerExposed>(); // Also, no shadows mr.receiveShadows = false; ImportUtils.SetCastShadows(mr, false); } }
private void CheckIfProcessingNormalMaps(XDocument xml) { var prefabProperties = xml.Root.Elements("Prefab").Elements("Property"); if (prefabProperties != null && prefabProperties.Count() > 0) { // Check to see if the normal map is defined and wanted to be used. var useNormalMapElement = prefabProperties.SingleOrDefault(o => o.Attribute("name").Value.CompareTo(ImportTiled2Unity.TiledPropertyName_UseNormalMap) == 0); if (useNormalMapElement != null) { // If the value is greater than 1 then the Tiled user intends to use a normal map if (ImportUtils.GetAttributeAsInt(useNormalMapElement, "value") > 0) { ImportTiled2Unity.ProcessingNormalMaps = true; } } } }
private void HandleTiledAttributes(GameObject gameObject, XElement goXml) { // Add the TiledMap component TiledMap map = gameObject.AddComponent <TiledMap>(); try { map.NumTilesWide = ImportUtils.GetAttributeAsInt(goXml, "numTilesWide"); map.NumTilesHigh = ImportUtils.GetAttributeAsInt(goXml, "numTilesHigh"); map.TileWidth = ImportUtils.GetAttributeAsInt(goXml, "tileWidth"); map.TileHeight = ImportUtils.GetAttributeAsInt(goXml, "tileHeight"); } catch { Debug.LogWarning(String.Format("Error adding TiledMap component. Are you using an old version of Tiled2Unity in your Unity project?")); GameObject.DestroyImmediate(map); } }
private void ImportTexturesFromXml(XDocument xml) { var texData = xml.Root.Elements("ImportTexture"); foreach (var tex in texData) { string name = tex.Attribute("filename").Value; string data = tex.Value; // The data is gzip compressed base64 string. We need the raw bytes. //byte[] bytes = ImportUtils.GzipBase64ToBytes(data); byte[] bytes = ImportUtils.Base64ToBytes(data); // Save and import the texture asset { string pathToSave = GetTextureAssetPath(name); ImportUtils.ReadyToWrite(pathToSave); File.WriteAllBytes(pathToSave, bytes); AssetDatabase.ImportAsset(pathToSave, ImportAssetOptions.ForceSynchronousImport); } // Create a material if needed in prepartion for the texture being successfully imported (NOTICE: Only if this is not a normal map) if (!name.Contains(ImportTiled2Unity.TiledNormalMapFileIdentification)) { string materialPath = GetMaterialAssetPath(name); Material material = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material; if (material == null) { // We need to create the material afterall // Use our custom shader if (ImportTiled2Unity.ProcessingNormalMaps) { material = new Material(Shader.Find("Tiled/TextureTintSnapNormal")); } else { material = new Material(Shader.Find("Tiled/TextureTintSnap")); } ImportUtils.ReadyToWrite(materialPath); AssetDatabase.CreateAsset(material, materialPath); } } } }
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)); } }
private void AssignLayerTo(GameObject gameObject, XElement xml) { string layerName = ImportUtils.GetAttributeAsString(xml, "layer", ""); if (String.IsNullOrEmpty(layerName)) return; int layerId = LayerMask.NameToLayer(layerName); if (layerId == -1) { string msg = String.Format("Layer '{0}' is not defined for '{1}'. Check project settings in Edit->Project Settings->Tags & Layers", layerName, GetFullGameObjectName(gameObject.transform)); Debug.LogError(msg); return; } // Set the layer on ourselves (and our children) AssignLayerIdTo(gameObject, layerId); }
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; }
private void AssignTagTo(GameObject gameObject, XElement xml) { string tag = ImportUtils.GetAttributeAsString(xml, "tag", ""); if (String.IsNullOrEmpty(tag)) return; // Let the user know if the tag doesn't exist in our project sttings try { gameObject.tag = tag; } catch (UnityException) { string msg = String.Format("Tag '{0}' is not defined for '{1}'. Check project settings in Edit->Project Settings->Tags & Layers", tag, GetFullGameObjectName(gameObject.transform)); Debug.LogError(msg); } }
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); }
private void CreateMaterialsFromInternalTextures(XDocument xml) { var texData = xml.Root.Elements("InternalTexture"); foreach (var tex in texData) { string texAssetPath = tex.Attribute("assetPath").Value; string materialPath = GetMaterialAssetPath(texAssetPath); // Create our material Material material = CreateMaterialFromXml(tex); // Assign to it the texture that is already internal to our Unity project Texture2D texture2d = AssetDatabase.LoadAssetAtPath(texAssetPath, typeof(Texture2D)) as Texture2D; material.SetTexture("_MainTex", texture2d); // Write the material to our asset database ImportUtils.ReadyToWrite(materialPath); ImportUtils.CreateOrReplaceAsset(material, materialPath); } }
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); HandleCustomProperties(tempPrefab, xmlPrefab, customImporters); // Part 2: Build out the prefab AddGameObjectsTo(tempPrefab, xmlPrefab, 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 prefabPath = ImportUtils.GetPrefabPath(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 void ImportMeshesFromXml(XDocument xml) { var meshData = xml.Root.Elements("ImportMesh"); foreach (var mesh in meshData) { // We're going to create/write a file that contains our mesh data as a Wavefront Obj file // The actual mesh will be imported from this Obj file string fname = mesh.Attribute("filename").Value; string data = mesh.Value; // The data is in base64 format. We need it as a raw string. string raw = ImportUtils.Base64ToString(data); // Save and import the asset string pathToMesh = GetMeshAssetPath(fname); ImportUtils.ReadyToWrite(pathToMesh); File.WriteAllText(pathToMesh, raw, Encoding.UTF8); AssetDatabase.ImportAsset(pathToMesh, ImportAssetOptions.ForceSynchronousImport); } }
private void OnPostprocessModel(GameObject gameObject) { if (!UseThisImporter()) { return; } // Each mesh renderer has the ability to set the a sort layer but it takes some work with Unity to expose it. foreach (MeshRenderer mr in gameObject.GetComponentsInChildren <MeshRenderer>()) { mr.gameObject.AddComponent <SortingLayerExposed>(); // Also, no shadows mr.receiveShadows = false; ImportUtils.SetCastShadows(mr, false); #if UNITY_4_0 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 // Do not set light probes or reflection probes in Unity 4.x #else mr.useLightProbes = false; mr.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off; #endif } }
private void ImportTexturesFromXml(XDocument xml) { var texData = xml.Root.Elements("ImportTexture"); foreach (var tex in texData) { string name = tex.Attribute("filename").Value; string data = tex.Value; // The data is gzip compressed base64 string. We need the raw bytes. //byte[] bytes = ImportUtils.GzipBase64ToBytes(data); byte[] bytes = ImportUtils.Base64ToBytes(data); // Save and import the texture asset { string pathToSave = GetTextureAssetPath(name); ImportUtils.ReadyToWrite(pathToSave); File.WriteAllBytes(pathToSave, bytes); AssetDatabase.ImportAsset(pathToSave, ImportAssetOptions.ForceSynchronousImport); } // Create a material if needed in prepartion for the texture being successfully imported { string materialPath = GetMaterialAssetPath(name); Material material = AssetDatabase.LoadAssetAtPath(materialPath, typeof(Material)) as Material; if (material == null) { // We need to create the material afterall // Use our custom shader material = CreateMaterialFromXml(tex); ImportUtils.ReadyToWrite(materialPath); AssetDatabase.CreateAsset(material, materialPath); } } } }
// 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 = GetXmlImportAssetPath(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 + ".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)); } // 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); material.SetColor("_AlphaColorKey", color); } return(material); }
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; } }
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 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 AddCollidersTo(GameObject gameObject, bool isTrigger, XElement xml) { // Box colliders foreach (XElement xmlBoxCollider2D in xml.Elements("BoxCollider2D")) { BoxCollider2D collider = gameObject.AddComponent <BoxCollider2D>(); collider.isTrigger = isTrigger; float width = ImportUtils.GetAttributeAsFloat(xmlBoxCollider2D, "width"); float height = ImportUtils.GetAttributeAsFloat(xmlBoxCollider2D, "height"); collider.size = new Vector2(width, height); #if UNITY_5_0 collider.offset = new Vector2(width * 0.5f, -height * 0.5f); #else collider.offset = new Vector2(width * 0.5f, -height * 0.5f); #endif } // Circle colliders foreach (XElement xmlCircleCollider2D in xml.Elements("CircleCollider2D")) { CircleCollider2D collider = gameObject.AddComponent <CircleCollider2D>(); collider.isTrigger = isTrigger; float radius = ImportUtils.GetAttributeAsFloat(xmlCircleCollider2D, "radius"); collider.radius = radius; #if UNITY_5_0 collider.offset = new Vector2(radius, -radius); #else collider.offset = new Vector2(radius, -radius); #endif } // Edge colliders foreach (XElement xmlEdgeCollider2D in xml.Elements("EdgeCollider2D")) { EdgeCollider2D collider = gameObject.AddComponent <EdgeCollider2D>(); collider.isTrigger = isTrigger; string data = xmlEdgeCollider2D.Element("Points").Value; // The data looks like this: // x0,y0 x1,y1 x2,y2 ... var points = from pt in data.Split(' ') let x = Convert.ToSingle(pt.Split(',')[0]) let y = Convert.ToSingle(pt.Split(',')[1]) select new Vector2(x, y); collider.points = points.ToArray(); } // Polygon colliders foreach (XElement xmlPolygonCollider2D in xml.Elements("PolygonCollider2D")) { PolygonCollider2D collider = gameObject.AddComponent <PolygonCollider2D>(); collider.isTrigger = isTrigger; var paths = xmlPolygonCollider2D.Elements("Path").ToArray(); collider.pathCount = paths.Count(); for (int p = 0; p < collider.pathCount; ++p) { string data = paths[p].Value; // The data looks like this: // x0,y0 x1,y1 x2,y2 ... var points = from pt in data.Split(' ') let x = Convert.ToSingle(pt.Split(',')[0]) let y = Convert.ToSingle(pt.Split(',')[1]) select new Vector2(x, y); collider.SetPath(p, points.ToArray()); } } }
private void AddCollidersTo(GameObject gameObject, bool isTrigger, XElement xml) { // Box colliders foreach (XElement xmlBoxCollider2D in xml.Elements("BoxCollider2D")) { BoxCollider2D collider = gameObject.AddComponent <BoxCollider2D>(); collider.isTrigger = isTrigger; float width = ImportUtils.GetAttributeAsFloat(xmlBoxCollider2D, "width"); float height = ImportUtils.GetAttributeAsFloat(xmlBoxCollider2D, "height"); collider.size = new Vector2(width, height); #if T2U_IS_UNITY_4 collider.center = new Vector2(width * 0.5f, -height * 0.5f); #else collider.offset = new Vector2(width * 0.5f, -height * 0.5f); #endif // Apply the offsets (if any) float offset_x = ImportUtils.GetAttributeAsFloat(xmlBoxCollider2D, "offsetX", 0); float offset_y = ImportUtils.GetAttributeAsFloat(xmlBoxCollider2D, "offsetY", 0); #if T2U_IS_UNITY_4 collider.center += new Vector2(offset_x, offset_y); #else collider.offset += new Vector2(offset_x, offset_y); #endif } // Circle colliders foreach (XElement xmlCircleCollider2D in xml.Elements("CircleCollider2D")) { CircleCollider2D collider = gameObject.AddComponent <CircleCollider2D>(); collider.isTrigger = isTrigger; float radius = ImportUtils.GetAttributeAsFloat(xmlCircleCollider2D, "radius"); collider.radius = radius; #if T2U_IS_UNITY_4 collider.center = new Vector2(radius, -radius); #else collider.offset = new Vector2(radius, -radius); #endif // Apply the offsets (if any) float offset_x = ImportUtils.GetAttributeAsFloat(xmlCircleCollider2D, "offsetX", 0); float offset_y = ImportUtils.GetAttributeAsFloat(xmlCircleCollider2D, "offsetY", 0); #if T2U_IS_UNITY_4 collider.center += new Vector2(offset_x, offset_y); #else collider.offset += new Vector2(offset_x, offset_y); #endif } // Edge colliders foreach (XElement xmlEdgeCollider2D in xml.Elements("EdgeCollider2D")) { EdgeCollider2D collider = gameObject.AddComponent <EdgeCollider2D>(); collider.isTrigger = isTrigger; string data = xmlEdgeCollider2D.Element("Points").Value; // The data looks like this: // x0,y0 x1,y1 x2,y2 ... var points = from pt in data.Split(' ') let x = Convert.ToSingle(pt.Split(',')[0], CultureInfo.InvariantCulture) let y = Convert.ToSingle(pt.Split(',')[1], CultureInfo.InvariantCulture) select new Vector2(x, y); collider.points = points.ToArray(); // Apply the offsets (if any) float offset_x = ImportUtils.GetAttributeAsFloat(xmlEdgeCollider2D, "offsetX", 0); float offset_y = ImportUtils.GetAttributeAsFloat(xmlEdgeCollider2D, "offsetY", 0); #if T2U_IS_UNITY_4 // This is kind of a hack for Unity 4.x which doesn't support offset/center on the edge collider var offsetPoints = from pt in points select new Vector2(pt.x + offset_x, pt.y + offset_y); collider.points = offsetPoints.ToArray(); #else collider.offset += new Vector2(offset_x, offset_y); #endif } // Polygon colliders foreach (XElement xmlPolygonCollider2D in xml.Elements("PolygonCollider2D")) { PolygonCollider2D collider = gameObject.AddComponent <PolygonCollider2D>(); collider.isTrigger = isTrigger; // Apply the offsets (if any) float offset_x = ImportUtils.GetAttributeAsFloat(xmlPolygonCollider2D, "offsetX", 0); float offset_y = ImportUtils.GetAttributeAsFloat(xmlPolygonCollider2D, "offsetY", 0); var paths = xmlPolygonCollider2D.Elements("Path").ToArray(); collider.pathCount = paths.Count(); for (int p = 0; p < collider.pathCount; ++p) { string data = paths[p].Value; // The data looks like this: // x0,y0 x1,y1 x2,y2 ... var points = from pt in data.Split(' ') let x = Convert.ToSingle(pt.Split(',')[0], CultureInfo.InvariantCulture) let y = Convert.ToSingle(pt.Split(',')[1], CultureInfo.InvariantCulture) #if T2U_IS_UNITY_4 // Hack for Unity 4.x select new Vector2(x + offset_x, y + offset_y); #else select new Vector2(x, y); #endif collider.SetPath(p, points.ToArray()); } #if !T2U_IS_UNITY_4 collider.offset += new Vector2(offset_x, offset_y); #endif } }
private void SetLayerComponentProperties(Tiled2Unity.Layer layer, XElement xml) { layer.Offset = new Vector2 { x = ImportUtils.GetAttributeAsFloat(xml, "offsetX", 0), y = ImportUtils.GetAttributeAsFloat(xml, "offsetY", 0) }; }