Exemplo n.º 1
0
    void LoadTileMap()
    {
        RemoveColliders();
        List <OTTile>allTiles = new List<OTTile>();
        Dictionary<int , OTTile>lookupTile = new Dictionary<int, OTTile>();

        if (tileMapXML == null)
        {
            if (tileSets == null)
                tileSets = new OTTileSet[] { };
            return;
        }

        XmlDocument xd = new XmlDocument();
        try
        {
            xd.LoadXml(tileMapXML.text);
        }
        catch(System.Exception)
        {
            Debug.LogError("TileMap XML - invalid XML!");
            return;
        }

        if (xd.DocumentElement == null)
        {
            Debug.LogError("TileMap XML - invalid XML!");
            return;
        }

        if (xd.DocumentElement.Name != "map")
        {
            Debug.LogError("TileMap XML - No Tiled Tilemap found!");
            return;
        }

        mapSize = new Vector2(AtI(xd.DocumentElement, "width"), AtI(xd.DocumentElement, "height"));
        mapTileSize = new Vector2(AtI(xd.DocumentElement, "tilewidth"), AtI(xd.DocumentElement, "tileheight"));

        XmlNodeList xmlTileSets = xd.DocumentElement.SelectNodes("tileset");
        if (xmlTileSets.Count == 0)
        {
            Debug.LogError("TileMap XML - No Tilesets found!");
            return;
        }

        XmlNodeList xmlLayers = xd.DocumentElement.SelectNodes("layer");
        if (xmlLayers.Count == 0)
        {
            Debug.LogError("TileMap XML - No Layers found!");
            return;
        }

        if (tileSets == null)
            tileSets = new OTTileSet[] { };

        tileSetLookup.Clear();
        System.Array.Resize<OTTileSet>(ref tileSets, xmlTileSets.Count);
        for (int i = 0; i < xmlTileSets.Count; i++)
        {
            if (tileSets[i] == null)
                tileSets[i] = new OTTileSet();

            OTTileSet ts = tileSets[i];
            XmlNode n = xmlTileSets[i];
            ts.name = AtS(n, "name");
            ts.firstGid = AtI(n, "firstgid");
            ts.margin = AtI(n, "margin");
            ts.spacing = AtI(n, "spacing");
            ts.tileSize = new Vector2(AtI(n, "tilewidth"), AtI(n, "tileheight"));

            XmlNode im = n.SelectSingleNode("image");
            string source = AtS(im, "source");

            if (tileSetImages.Length > 0)
            {
                for (int ii = 0; ii < tileSetImages.Length; ii++)
                    if (source.IndexOf(tileSetImages[ii].name) >= 0)
                        ts.image = tileSetImages[ii];
            }

            ts.imageSize = new Vector2(AtI(im, "width"), AtI(im, "height"));
            ts.tilesXY = new Vector2(Mathf.Round((ts.imageSize.x-(ts.margin*2)) / (ts.tileSize.x+ts.spacing)),
                Mathf.Round((ts.imageSize.y-(ts.margin*2)) / (ts.tileSize.y+ts.spacing)));
            int tileCount = (int)(ts.tilesXY.x * ts.tilesXY.y);

            int idx = 0;
            for (int ii = ts.firstGid; ii < ts.firstGid + tileCount; ii++)
            {
                if (!tileSetLookup.ContainsKey(ii))
                    tileSetLookup.Add(ii, ts);

                OTTile tile = new OTTile();
                XmlNode tileNode = n.SelectSingleNode("tile[@id='"+idx+"']");
                tile.index = idx++;
                if (tileNode!=null)
                {
                    tile.collider = TileProp(tileNode,"collider");
                    tile.name = TileProp(tileNode,"name");
                    tile.material = TileProp(tileNode,"material");
                    tile.display = true;
                    string sDisplay = TileProp(tileNode,"display").ToLower();
                    if (sDisplay=="none" || sDisplay=="false" || sDisplay=="hidden" || sDisplay=="0")
                        tile.display = false;
                    try
                    {
                        tile.height = System.Convert.ToInt16(TileProp(tileNode,"height"));
                    }
                    catch(System.Exception)
                    {
                        tile.height = 0;
                    }
                    if (tile.height == 0) tile.height = (int)mapTileSize.x;
                    if (tile.height == 0) tile.height = 10;
                    tile.gid = ii;
                    if (tile.name=="") tile.name = "tileGUID"+ii;
                    allTiles.Add(tile);
                    lookupTile.Add(ii,tile);
                }
            }
        }

        if (layers == null)
            layers = new OTTileMapLayer[] { };

        System.Array.Resize<OTTileMapLayer>(ref layers, xmlLayers.Count);
        for (int i = 0; i < xmlLayers.Count; i++)
        {
            if (layers[i] == null)
                layers[i] = new OTTileMapLayer();

            OTTileMapLayer l = layers[i];
            XmlNode n = xmlLayers[i];
            l.name = AtS(n, "name");
            l.depth = 0 - i;
            l.layerSize = new Vector2(AtI(n, "width"), AtI(n, "height"));
            int tileCount = (int)(l.layerSize.x * l.layerSize.y);

            if (l.tiles.Length!=tileCount)
                System.Array.Resize<int>(ref l.tiles, tileCount);

            try
            {
                try
                {
                    XmlNodeList props = n.SelectSingleNode("properties").SelectNodes("property");
                    if (HasProp(props, "depth"))
                        l.depth = GetPropI(props, "depth");
                }
                catch (System.Exception)
                {
                }

                XmlNodeList tiles = n.SelectSingleNode("data").SelectNodes("tile");
                if (tiles.Count != tileCount)
                    Debug.LogWarning("TileMap XML - Invalid number of tiles " + tiles.Count+" on layer "+l.name+", size "+l.layerSize.x+" x "+l.layerSize.y+
                    " , so expected "+tileCount+" tiles.");

                for (int li = 0; li < tileCount; li++)
                    l.tiles[li] = 0;

                for (int li = 0; li < tiles.Count; li++)
                {
                    int gid = AtI(tiles[li],"gid");
                    if (lookupTile.ContainsKey(gid))
                    {
                        if (lookupTile[gid].display)
                            l.tiles[li] = AtI(tiles[li],"gid");
                        else
                            l.tiles[li] = 0;
                    }
                    else
                        l.tiles[li] = AtI(tiles[li],"gid");
                }
            }
            catch (System.Exception)
            {
                Debug.LogError("TileMap XML - Could not load tiles from layer " + l.name);
            }
        }

        meshDirty = true;
        isDirty = true;

        size = new Vector2(mapSize.x * mapTileSize.x, mapSize.y * mapTileSize.y);

        if (generateColliders)
            CreateColliders(allTiles);
    }
Exemplo n.º 2
0
    void CreateTileColliders(OTTile tile)
    {
        // create tilemap for collider creation
        int[] tiles = new int[] {};
        for (int i = 0; i < layers.Length; i++)
        {
            OTTileMapLayer l = layers[i];
            if (i==0)
            {
                tiles = l.tiles.Clone() as int[];
                for (int t=0; t<tiles.Length; t++)
                    if (tiles[t]!=tile.gid) tiles[t] = 0;
            }
            else
            {
                for (int t=0; t<l.tiles.Length; t++)
                    if (l.tiles[t]==tile.gid) tiles[t] = tile.gid;
            }
        }

        Vector2 pos = new Vector2(0,0);
        while (!pos.Equals(mapSize))
        {
            if (tiles[(int)((pos.y * mapSize.x)+pos.x)] == tile.gid)
            {
                Vector2 old = pos;
                Vector2 col = Vector2.one;
                while (tiles[(int)((pos.y * mapSize.x)+pos.x)]==tile.gid)
                {
                    if (pos.y==old.y)
                    {
                        if (pos.x - old.x + 1 >= col.x && pos.y - old.y +1 >= col.y)
                            col = new Vector2(pos.x - old.x + 1, pos.y - old.y +1);
                    }
                    else
                    {
                        if (pos.x - old.x + 1 > col.x)
                            break;
                        else
                            col = new Vector2(col.x, pos.y - old.y +1);
                    }
                    pos.x++;
                    if (pos.x==mapSize.x)
                    {
                        pos.x = old.x;
                        pos.y++;
                        if (pos.y==mapSize.y)
                            break;
                    }
                    else
                    {
                        if (tiles[(int)((pos.y * mapSize.x)+pos.x)]!=tile.gid)
                        {
                            if (col.y > 1 && (pos.x - old.x + 1 < col.x))
                            {
                                --col.y;
                                break;
                            }

                            pos.x = old.x;
                            pos.y++;
                            if (pos.y==mapSize.y)
                                break;

                        }
                    }
                }
                pos = old;

                for (int dx = 0; dx < col.x; dx++)
                    for (int dy = 0; dy < col.y; dy++)
                        tiles[(int)(((pos.y + dy) * mapSize.x)+(pos.x+dx))] = 0;

                Transform colliders = transform.FindChild("colliders");
                if (colliders == null)
                {
                    GameObject g = new GameObject();
                    g.name = "colliders";
                    colliders = g.transform;
                    colliders.parent = transform;
                    colliders.localScale = Vector3.one;
                    colliders.localPosition = Vector3.zero;
                }
                Transform tileColliders = colliders.FindChild(tile.name);
                if (tileColliders == null)
                {
                    GameObject g = new GameObject();
                    g.name = tile.name;
                    tileColliders = g.transform;
                    tileColliders.parent = colliders;
                    tileColliders.localScale = Vector3.one;
                    tileColliders.localPosition = Vector3.zero;
                }

                GameObject go = new GameObject();
                if (tile.collider.ToLower() != "collider")
                    go.name = "tilemapTrigger";
                else
                    go.name = "tilemapCollider";

                OTTileSet ts = tileSetLookup[tile.gid];

                col.x *= ts.tileSize.x / mapTileSize.x;
                float fy = ts.tileSize.y / mapTileSize.y;
                col.y *= fy;

                if (OT.world == OT.World.WorldTopDown2D)
                {
                    go.transform.localScale = new Vector3(col.x * mapTileSize.x, tile.height, col.y * mapTileSize.y);
                    go.transform.position = transform.position -
                        new Vector3((mapSize.x * mapTileSize.x)/2,tile.height/3,  (-mapSize.y * mapTileSize.y)/2);
                    go.transform.position += new Vector3((pos.x * mapTileSize.x) + mapTileSize.x/2,0,  -pos.y * mapTileSize.y - (mapTileSize.y/2));
                    go.transform.position += new Vector3((col.x * mapTileSize.x)/2 - mapTileSize.x/2,0, (-col.y * mapTileSize.y)/2 + mapTileSize.y/2);
                    if (fy>1)
                      go.transform.position += new Vector3(0, 0, mapTileSize.y * (fy-1));
                }
                else
                {
                    go.transform.localScale = new Vector3(col.x * mapTileSize.x, col.y * mapTileSize.y, tile.height);
                    go.transform.position = transform.position -
                        new Vector3((mapSize.x * mapTileSize.x)/2, (-mapSize.y * mapTileSize.y)/2, tile.height/3);
                    go.transform.position += new Vector3((pos.x * mapTileSize.x) + mapTileSize.x/2, -pos.y * mapTileSize.y - (mapTileSize.y/2),0);
                    go.transform.position += new Vector3((col.x * mapTileSize.x)/2 - mapTileSize.x/2, (-col.y * mapTileSize.y)/2 + mapTileSize.y/2,0);
                    if (fy>1)
                      go.transform.position += new Vector3(0, mapTileSize.y * (fy-1),0);
                }

                go.transform.parent = tileColliders;
                BoxCollider box = go.AddComponent<BoxCollider>() as BoxCollider;

                if (tile.material != "")
                {
                    PhysicMaterial pm = Resources.Load(tile.material) as PhysicMaterial;
                    if (pm != null)
                        box.material = pm;
                }

                if (tile.collider.ToLower() == "collider")
                {
                    Rigidbody rb = go.AddComponent<Rigidbody>() as Rigidbody;
                    // rb.useGravity = false;
                    rb.isKinematic = true;
                }
                else
                    box.isTrigger = true;

            }
            else
            {
                pos.x++;
                if (pos.x==mapSize.x)
                {
                    pos.x = 0;
                    pos.y++;
                    if (pos.y==mapSize.y)
                        break;
                }
            }
        }
    }