/// <summary> /// Load Map XML from a WWW path /// </summary> /// <param name="wwwPath">WWW path to load XML from</param> /// <returns>is loaded or not</returns> IEnumerator LoadFromPath(string wwwPath) { string result; string filePath = string.Concat(_mapPath, _mapName, _mapExtension); if (!filePath.Contains("://")) filePath = string.Concat("file://", filePath); //Debug.Log(filePath); WWW www = new WWW(filePath); yield return www; result = www.text; UsingStreamingAssetsPath = true; NanoXMLDocument document = new NanoXMLDocument(result); Initialize(document); }
/// <summary> /// Create a Tiled Map using TextAsset as parameter /// </summary> /// <param name="mapText">Map's TextAsset</param> /// <param name="mapPath">Path to XML folder, so we can read relative paths for tilesets</param> /// <param name="parent">This map's gameobject parent</param> /// <param name="baseTileMaterial">Base material to be used for the Tiles</param> /// <param name="sortingOrder">Base sorting order for the tile layers</param> /// <param name="mapPath">Path to XML folder, so we can read relative paths for tilesets</param> /// <param name="makeUnique">array with bools to make unique tiles for each tile layer</param> /// <param name="onMapFinishedLoading">Callback for when map finishes loading</param> /// <param name="simpleTileObjectCalculation">true to generate simplified tile collisions</param> /// <param name="tileObjectEllipsePrecision">Tile collisions ellipsoide approximation precision</param> /// <param name="clipperArcTolerance">Clipper arc angle tolerance</param> /// <param name="clipperDeltaOffset">Clipper delta offset</param> /// <param name="clipperEndType">Clipper Polygon end type</param> /// <param name="clipperJoinType">Clipper join type</param> /// <param name="clipperMiterLimit">Clipper limit for Miter join type</param> public Map(TextAsset mapText, string mapPath, GameObject parent, Material baseTileMaterial, int sortingOrder, bool makeUnique, Action<Map> onMapFinishedLoading = null, int tileObjectEllipsePrecision = 16, bool simpleTileObjectCalculation = true, double clipperArcTolerance = 0.25, double clipperMiterLimit = 2.0, ClipperLib.JoinType clipperJoinType = ClipperLib.JoinType.jtRound, ClipperLib.EndType clipperEndType = ClipperLib.EndType.etClosedPolygon, float clipperDeltaOffset = 0) { _tileObjectEllipsePrecision = tileObjectEllipsePrecision; _simpleTileObjectCalculation = simpleTileObjectCalculation; _clipperArcTolerance = clipperArcTolerance; _clipperDeltaOffset = clipperDeltaOffset; _clipperEndType = clipperEndType; _clipperJoinType = clipperJoinType; _clipperMiterLimit = clipperMiterLimit; NanoXMLDocument document = new NanoXMLDocument(mapText.text); _mapName = mapText.name; Parent = parent; DefaultSortingOrder = sortingOrder; GlobalMakeUniqueTiles = makeUnique; BaseTileMaterial = baseTileMaterial; _mapPath = mapPath; OnMapFinishedLoading = onMapFinishedLoading; Initialize(document); }
/// <summary> /// Finally build TileSet info using read data /// </summary> /// <param name="tileSetData">TileSet raw XML</param> /// <param name="path">External TileSet root directory</param> /// <param name="firstID">TileSet's firstID (external TileSet does not save this info)</param> void BuildExternalTileSet(string tileSetData, string path, int firstID = 1) { NanoXMLDocument externalTileSet = new NanoXMLDocument(tileSetData); NanoXMLNode externalTileSetNode = externalTileSet.RootNode; new TileSet(externalTileSetNode, path, this, UsingStreamingAssetsPath, OnFinishedLoadingTileSet, firstID); }
/// <summary> /// Initializes, Reads this Map's info /// </summary> /// <param name="document">NanoXMLDocument containing Map's XML</param> void Initialize(NanoXMLDocument document) { MapNode = document.RootNode; Orientation = (Orientation)Enum.Parse(typeof(Orientation), MapNode.GetAttribute("orientation").Value, true); Width = int.Parse(MapNode.GetAttribute("width").Value, CultureInfo.InvariantCulture); Height = int.Parse(MapNode.GetAttribute("height").Value, CultureInfo.InvariantCulture); TileWidth = int.Parse(MapNode.GetAttribute("tilewidth").Value, CultureInfo.InvariantCulture); TileHeight = int.Parse(MapNode.GetAttribute("tileheight").Value, CultureInfo.InvariantCulture); if (MapNode.GetAttribute("version") != null) { Version = MapNode.GetAttribute("version").Value; } else Version = string.Empty; if (MapNode.GetAttribute("renderorder") != null) { string renderOrder = MapNode.GetAttribute("renderorder").Value; MapRenderOrder = (RenderOrder)Enum.Parse(typeof(RenderOrder), renderOrder.Replace('-', '_'), true); } else MapRenderOrder = RenderOrder.Right_Down; if (MapNode.GetAttribute("backgroundcolor") != null) { string color = MapNode.GetAttribute("backgroundcolor").Value; string r = color.Substring(1, 2); string g = color.Substring(3, 2); string b = color.Substring(5, 2); this.BackgroundColor = new Color( (byte)Convert.ToInt32(r, 16), (byte)Convert.ToInt32(g, 16), (byte)Convert.ToInt32(b, 16)); } if (_mapName == null) _mapName = "Map"; if (!_mapPath.EndsWith(Path.AltDirectorySeparatorChar.ToString())) _mapPath = _mapPath + Path.AltDirectorySeparatorChar; MapObject = new GameObject(_mapName); Transform mapObjectTransform = MapObject.transform; mapObjectTransform.parent = Parent.transform; mapObjectTransform.localPosition = Vector3.zero; MapObject.layer = mapObjectTransform.parent.gameObject.layer; NanoXMLNode propertiesElement = MapNode["properties"]; if (propertiesElement != null) Properties = new PropertyCollection(propertiesElement); TileSets = new List<TileSet>(); Tiles = new Dictionary<int, Tile>(); _tileSetsToLoaded = 0; _numberOfTileSetsToLoad = 0; // First get how many tilesets we need to load foreach (NanoXMLNode node in MapNode.SubNodes) { if (node.Name.Equals("tileset")) _numberOfTileSetsToLoad++; } // Maps might not have any tileset, being just a tool for object placement :P if (_numberOfTileSetsToLoad < 1) { ContinueLoadingTiledMapAfterTileSetsLoaded(); } // Then load all of them. After all loaded, continue with map loading foreach (NanoXMLNode node in MapNode.SubNodes) { if (node.Name.Equals("tileset")) { if (node.GetAttribute("source") != null) { int firstID = int.Parse(node.GetAttribute("firstgid").Value, CultureInfo.InvariantCulture); if (UsingStreamingAssetsPath) { // Run coroutine for www using TaskManager new Task(LoadExternalTileSet(node, _mapPath, firstID), true); } else { // Parse the path string path = node.GetAttribute("source").Value; string rootPath = Directory.GetParent(_mapPath).FullName; string appPath = Path.GetFullPath(Application.dataPath.Replace("/Assets", "")); while (path.StartsWith("../")) { rootPath = Directory.GetParent(rootPath).FullName; path = path.Remove(0, 3); } rootPath = rootPath.Replace(appPath + Path.DirectorySeparatorChar, ""); path = Path.GetDirectoryName(path) + Path.AltDirectorySeparatorChar + Path.GetFileNameWithoutExtension(path); if (path.StartsWith("/")) path = path.Remove(0, 1); rootPath = rootPath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); if (rootPath.Length > 0) rootPath += Path.AltDirectorySeparatorChar; path = rootPath + path; //path = path.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); TextAsset externalTileSetTextAsset = Resources.Load<TextAsset>(path); BuildExternalTileSet(externalTileSetTextAsset.text, Directory.GetParent(path).ToString(), firstID); } } else { new TileSet(node, _mapPath, this, UsingStreamingAssetsPath, OnFinishedLoadingTileSet); } } } }
private void ReadPropertiesAndVariables() { if (_tiledMapComponent.tileLayers != null && _tiledMapComponent.MakeUniqueTiles != null && _tiledMapComponent.tileLayers.Length > _tiledMapComponent.MakeUniqueTiles.Length) _changedMap = true; if (_changedMap || _tiledMapComponent.mapProperties == null || _tiledMapComponent.objectLayerNodes == null || _tiledMapComponent.tileLayersProperties == null || _tiledMapComponent.objectLayersProperties == null || _tiledMapComponent.imageLayersProperties == null || _tiledMapComponent.objectLayers == null || _tiledMapComponent.generateCollider == null || _tiledMapComponent.collidersIs2D == null || _tiledMapComponent.collidersWidth == null || _tiledMapComponent.collidersZDepth == null || _tiledMapComponent.collidersIsInner == null || _tiledMapComponent.collidersIsTrigger == null || _tiledMapComponent.tileLayers == null || _tiledMapComponent.imageLayers == null || _tiledMapComponent.tileLayersFoldoutProperties == null || _tiledMapComponent.objectLayersFoldoutProperties == null || _tiledMapComponent.imageLayersFoldoutProperties == null || _tiledMapComponent.MakeUniqueTiles == null ){ NanoXMLDocument document = new NanoXMLDocument(_tiledMapComponent.MapTMX.text); NanoXMLNode mapNode = document.RootNode; List<Property> mapProperties = new List<Property>(); List<NanoXMLNode> objectLayerNodes = new List<NanoXMLNode>(); List<string> objectLayers = new List<string>(); List<bool> generateCollider = new List<bool>(); List<bool> collidersIs2D = new List<bool>(); List<float> collidersWidth = new List<float>(); List<float> collidersZDepth = new List<float>(); List<bool> collidersIsInner = new List<bool>(); List<bool> collidersIsTrigger = new List<bool>(); List<string> tileLayers = new List<string>(); List<string> imageLayers = new List<string>(); List<bool> makeUniqueTiles = new List<bool>(); List<bool> tileLayersFoldoutProperties = new List<bool>(); List<bool> objectLayersFoldoutProperties = new List<bool>(); List<bool> imageLayersFoldoutProperties = new List<bool>(); Dictionary<int, List<Property>> tileLayersProperties = new Dictionary<int,List<Property>>(); Dictionary<int, List<Property>> objectLayersProperties = new Dictionary<int,List<Property>>(); Dictionary<int, List<Property>> imageLayersProperties = new Dictionary<int, List<Property>>(); foreach (NanoXMLNode layerNode in mapNode.SubNodes) { if (layerNode.Name.Equals("properties")) { foreach (var property in layerNode.SubNodes) { mapProperties.Add( new Property( property.GetAttribute("name").Value, property.GetAttribute("value").Value ) ); } } if (layerNode.Name.Equals("objectgroup")) { objectLayerNodes.Add(layerNode); objectLayers.Add(layerNode.GetAttribute("name").Value); generateCollider.Add(false); collidersIs2D.Add(true); collidersWidth.Add(1); collidersZDepth.Add(0); collidersIsInner.Add(false); collidersIsTrigger.Add(false); // properties objectLayersFoldoutProperties.Add(false); objectLayersProperties.Add(objectLayerNodes.Count - 1, new List<Property>()); foreach (var subNodes in layerNode.SubNodes) { if (subNodes.Name.Equals("properties")) { foreach (var property in subNodes.SubNodes) { objectLayersProperties[objectLayerNodes.Count - 1].Add( new Property( property.GetAttribute("name").Value, property.GetAttribute("value").Value ) ); } } } } if (layerNode.Name.Equals("layer")) { tileLayers.Add(layerNode.GetAttribute("name").Value); // Make Unique Tiles makeUniqueTiles.Add(false); // properties tileLayersFoldoutProperties.Add(false); tileLayersProperties.Add(tileLayers.Count - 1, new List<Property>()); foreach (var subNodes in layerNode.SubNodes) { if (subNodes.Name.Equals("properties")) { foreach (var property in subNodes.SubNodes) { tileLayersProperties[tileLayers.Count - 1].Add( new Property( property.GetAttribute("name").Value, property.GetAttribute("value").Value ) ); } } } } if (layerNode.Name.Equals("imagelayer")) { imageLayers.Add(layerNode.GetAttribute("name").Value); // properties imageLayersFoldoutProperties.Add(false); imageLayersProperties.Add(imageLayers.Count - 1, new List<Property>()); foreach (var subNodes in layerNode.SubNodes) { if (subNodes.Name.Equals("properties")) { foreach (var property in subNodes.SubNodes) { imageLayersProperties[imageLayers.Count - 1].Add( new Property( property.GetAttribute("name").Value, property.GetAttribute("value").Value ) ); } } } } } if (_changedMap || _tiledMapComponent.mapProperties == null) _tiledMapComponent.mapProperties = mapProperties.ToArray(); if (_changedMap || _tiledMapComponent.objectLayerNodes == null) _tiledMapComponent.objectLayerNodes = objectLayerNodes.ToArray(); if (_changedMap || _tiledMapComponent.tileLayersProperties == null) _tiledMapComponent.tileLayersProperties = new Dictionary<int,List<Property>>(tileLayersProperties); if (_changedMap || _tiledMapComponent.objectLayersProperties == null) _tiledMapComponent.objectLayersProperties = objectLayersProperties; if (_changedMap || _tiledMapComponent.imageLayersProperties == null) _tiledMapComponent.imageLayersProperties = imageLayersProperties; if (_changedMap || _tiledMapComponent.objectLayers == null) _tiledMapComponent.objectLayers = objectLayers.ToArray(); if (_changedMap || _tiledMapComponent.generateCollider == null) _tiledMapComponent.generateCollider = generateCollider.ToArray(); if (_changedMap || _tiledMapComponent.collidersIs2D == null) _tiledMapComponent.collidersIs2D = collidersIs2D.ToArray(); if (_changedMap || _tiledMapComponent.collidersWidth == null) _tiledMapComponent.collidersWidth = collidersWidth.ToArray(); if (_changedMap || _tiledMapComponent.collidersZDepth == null) _tiledMapComponent.collidersZDepth = collidersZDepth.ToArray(); if (_changedMap || _tiledMapComponent.collidersIsInner == null) _tiledMapComponent.collidersIsInner = collidersIsInner.ToArray(); if (_changedMap || _tiledMapComponent.collidersIsTrigger == null) _tiledMapComponent.collidersIsTrigger = collidersIsTrigger.ToArray(); if (_changedMap || _tiledMapComponent.tileLayers == null) _tiledMapComponent.tileLayers = tileLayers.ToArray(); if (_changedMap || _tiledMapComponent.imageLayers == null) _tiledMapComponent.imageLayers = imageLayers.ToArray(); if (_changedMap || _tiledMapComponent.tileLayersFoldoutProperties == null) _tiledMapComponent.tileLayersFoldoutProperties = tileLayersFoldoutProperties.ToArray(); if (_changedMap || _tiledMapComponent.objectLayersFoldoutProperties == null) _tiledMapComponent.objectLayersFoldoutProperties = objectLayersFoldoutProperties.ToArray(); if (_changedMap || _tiledMapComponent.imageLayersFoldoutProperties == null) _tiledMapComponent.imageLayersFoldoutProperties = imageLayersFoldoutProperties.ToArray(); if (_changedMap || _tiledMapComponent.MakeUniqueTiles == null) _tiledMapComponent.MakeUniqueTiles = makeUniqueTiles.ToArray(); if(_changedMap) _changedMap = false; } }
/// <summary> /// Create a Tiled Map using TextAsset as parameter /// </summary> /// <param name="mapText">Map's TextAsset</param> /// <param name="mapPath">Path to XML folder, so we can read relative paths for tilesets</param> /// <param name="onMapFinishedLoading">Callback for when map xml finishes loading</param> public Map(TextAsset mapText, string mapPath, Action<Map> onMapFinishedLoading = null) { NanoXMLDocument document = new NanoXMLDocument(mapText.text); _mapName = mapText.name; _mapPath = mapPath; OnMapFinishedLoading = onMapFinishedLoading; ParseMapXML(document); }
/// <summary> /// Create a Tiled Map using the raw XML string as parameter. /// </summary> /// <param name="mapXML">Raw map XML string</param> /// <param name="MapName">Map's name</param> /// <param name="mapPath">Path to XML folder, so we can read relative paths for tilesets</param> /// <param name="onMapFinishedLoading">Callback for when map xml finishes loading</param> public Map(string mapXML, string MapName, string mapPath, Action<Map> onMapFinishedLoading = null) { NanoXMLDocument document = new NanoXMLDocument(mapXML); _mapName = MapName; _mapPath = mapPath; OnMapFinishedLoading = onMapFinishedLoading; ParseMapXML(document); }
/// <summary> /// Initializes, Reads this Map's XML info /// </summary> /// <param name="document">NanoXMLDocument containing Map's XML</param> void ParseMapXML(NanoXMLDocument document) { MapNode = document.RootNode; Orientation orientation = (Orientation)Enum.Parse(typeof(Orientation), MapNode.GetAttribute("orientation").Value, true); int width = int.Parse(MapNode.GetAttribute("width").Value, CultureInfo.InvariantCulture); int height = int.Parse(MapNode.GetAttribute("height").Value, CultureInfo.InvariantCulture); int tileWidth = int.Parse(MapNode.GetAttribute("tilewidth").Value, CultureInfo.InvariantCulture); int tileHeight = int.Parse(MapNode.GetAttribute("tileheight").Value, CultureInfo.InvariantCulture); if (MapNode.GetAttribute("version") != null) { Version = MapNode.GetAttribute("version").Value; } else Version = string.Empty; RenderOrder mapRenderOrder = RenderOrder.Right_Down; if (MapNode.GetAttribute("renderorder") != null) { string renderOrder = MapNode.GetAttribute("renderorder").Value; mapRenderOrder = (RenderOrder)Enum.Parse(typeof(RenderOrder), renderOrder.Replace('-', '_'), true); } StaggerAxis mapStaggerAxis = StaggerAxis.Y; if (MapNode.GetAttribute("staggeraxis") != null) { string staggeraxis = MapNode.GetAttribute("staggeraxis").Value; mapStaggerAxis = (StaggerAxis)Enum.Parse(typeof(StaggerAxis), staggeraxis, true); } StaggerIndex mapStaggerIndex = StaggerIndex.Odd; if (MapNode.GetAttribute("staggerindex") != null) { string staggerindex = MapNode.GetAttribute("staggerindex").Value; mapStaggerIndex = (StaggerIndex)Enum.Parse(typeof(StaggerIndex), staggerindex, true); } int hexSideLength = 0; if (MapNode.GetAttribute("hexsidelength") != null) { hexSideLength = int.Parse(MapNode.GetAttribute("hexsidelength").Value, CultureInfo.InvariantCulture); } if (MapNode.GetAttribute("nextobjectid") != null) { NextObjectID = int.Parse(MapNode.GetAttribute("nextobjectid").Value, CultureInfo.InvariantCulture); } else NextObjectID = 0; Color32 backgroundColor = new Color32(128, 128, 128, 255); if (MapNode.GetAttribute("backgroundcolor") != null) { string color = MapNode.GetAttribute("backgroundcolor").Value; string r = color.Substring(1, 2); string g = color.Substring(3, 2); string b = color.Substring(5, 2); backgroundColor = new Color32( (byte)Convert.ToInt32(r, 16), (byte)Convert.ToInt32(g, 16), (byte)Convert.ToInt32(b, 16),255); } MapRenderParameter = new MapRenderParameters(orientation, mapRenderOrder, mapStaggerAxis, mapStaggerIndex, width, height, tileWidth, tileHeight, hexSideLength, backgroundColor); if (_mapName == null) _mapName = "Map"; if (!_mapPath.EndsWith(Path.AltDirectorySeparatorChar.ToString())) _mapPath = _mapPath + Path.AltDirectorySeparatorChar; NanoXMLNode propertiesElement = MapNode["properties"]; if (propertiesElement != null) { Properties = new PropertyCollection(propertiesElement); } TileSets = new List<TileSet>(); Tiles = new Dictionary<int, Tile>(); _tileSetsToLoaded = 0; _numberOfTileSetsToLoad = 0; // First get how many tilesets we need to load foreach (NanoXMLNode node in MapNode.SubNodes) { if (node.Name.Equals("tileset")) _numberOfTileSetsToLoad++; } // Maps might not have any tileset, being just a tool for object placement :P if (_numberOfTileSetsToLoad < 1) { ContinueLoadingTiledMapAfterTileSetsLoaded(); } // Then load all of them. After all loaded, continue with map loading foreach (NanoXMLNode node in MapNode.SubNodes) { if (node.Name.Equals("tileset")) { if (node.GetAttribute("source") != null) { int firstID = int.Parse(node.GetAttribute("firstgid").Value, CultureInfo.InvariantCulture); if (UsingStreamingAssetsPath) { // Run coroutine for www using TaskManager new Task(LoadExternalTileSet(node, _mapPath, firstID), true); } else { // Parse the path string path = Utils.XUniTMXHelpers.ParsePath(_mapPath, node.GetAttribute("source").Value); TextAsset externalTileSetTextAsset = Resources.Load<TextAsset>(path); BuildExternalTileSet(externalTileSetTextAsset.text, Directory.GetParent(path).ToString(), firstID); } } else { OnFinishedLoadingTileSet(new TileSet(node, _mapPath, this, UsingStreamingAssetsPath)); } } } }
/// <summary> /// Load Map XML from a WWW path /// </summary> /// <param name="wwwPath">WWW path to load XML from</param> /// <returns>is loaded or not</returns> IEnumerator LoadFromPath(string wwwPath) { string result; string filePath = string.Concat(_mapPath, _mapName, _mapExtension); if (!filePath.Contains("://")) filePath = string.Concat("file://", filePath); WWW www = new WWW(filePath); yield return www; if (www.error != null) { Debug.LogError(www.error); } else { result = www.text; UsingStreamingAssetsPath = true; NanoXMLDocument document = new NanoXMLDocument(result); ParseMapXML(document); } }