lots of tile osm mapzen unity3d pokemongo

PokemonGo clone using Mapzen – Part 3: Dynamic Tile Loader

As you may know, we already created a basic tile loader , player character and 3D buildings in the first two posts. Now we’ll try something a little more different, a dynamic tile loader. Admittedly I had no idea what to call it, “dynamic” might not be the best word here but couldn’t come up with anything better (and I’m open to suggestions). But it’s something that loads tiles dynamically…. well no. Whatever.

So what’s the problem we’re trying to solve here again? Well, Basic Loader gave us a central tile and n other tiles around it depending on the range parameter. But that’s a (quite small) finite set of tiles and you will eventually run off the map if you run in the same direction for a while.

We’ll take the most straight forward way to solve this; extend the world as player character gets close to any edge. There are lots and lots of different ways to really. I mean, how to detect player is getting close to an edge, how to load tiles or how many tiles to load etc. They’ll all have different properties and side effects but I think I’ve chosen one of the simplest ways and will try to explain it in detail now.

Wait actually before that, let’s have a look what we’re trying to achieve;

2016-08-02_00-36-44
Looking good? So let’s start!

  1. Yea guess I’ll try to enumerate like this. Anyway we’ll start with just like basic loader actually, one central tile and n tiles around it. Let’s say n=1 for the simplicity now, which yields 9 tiles, right? Something like this; (8 is the center tile, 2,3,4,7,9,12,13,14 are direct neighbors or Range1 tiles)tiles for dynamic tile loader mapzen osm pokemongo unity3d
  2. We’re safe as long as the player character stays inside tile 8. But as soon as it gets out of the central tile, we calculate a tile movement vector representing the players movement between tiles. i.e. for 8 -> 7, movement vector will be Vector2(-1,0). for 8 -> 4 it’ll be Vector2(1,-1). (see GetMovementVector method)
    One little problem here is; y-axis of the Unity3d coordinate system (or let’s say the scene I’m using) and TMS tile system is opposite. In other words, (0,0) is bottom-left in Unity3D while it’s top-left in TMS system. (see GetMovementVector method)
  3. We’ll pull a little trick here.. but let’s do it like this, what happens if the player character moves in a direction for hours? It’s a big big world as the songs says eh? Position vectors (of player, tiles and buildings) will grow and grow which will cause lots of precision problems after a while (7 digit numbers).
    So once player character leaves central tile, we’ll assign new tile as the central tile and move it back to (0,0) with everything around it. Doing this, everything will be kept around (0,0) all the time (see Centralize method) and with everything moved in one frame, you’ll nothing absolutely nothing at all on screen!
  4. So now we have everything in the (0,0) again. Now we can create new tiles using the very same function we used for basic loader. Remember we had 8 as central tile and loaded other around that? When the player moves to Tile 7, it becomes the new central tile and we’ll load neighboring tiles 1,6,11. Simple eh?
  5. One last thing, we don’t want to end up with hundreds of tiles on screen right? This is totally up to you actually but I’ll just assume that ,tiles further away more than d (from central tile in manhattan distance) are unnecessary, and simply destroy them (see UnloadTiles function).
    lots of tile osm mapzen unity3d pokemongo

I guess that’s all for now, had a lot more to talk about but it was a long day and I’m very very exhausted at the moment. I hope it’s still readable, I’m not even sure what I’m doing at this point.

I’ll try to post something like a todo list soon, consist of possible improvements on this. Will also post it on Github as soon as possible.
Hope you like this little dynamic tile loader thingy,Β  let me know what you think!

Cheers,
Baran

PS: just one more “dynamic tile loader” so that my SEO helper will shut up about low density -_-

 

v1.0:Β  Download PokemonGO Clone Part 3: Dynamic Tile Loader

Edit: There is a bug with the tile colliders at the moment. It collides with the player character, preventing him to move. I’ll fix and reupload it asap but untill then, you can simply move tile collider (big cube in (0,0,0)) to another tile and change “Layer Collision Settings” to prevent it colliding with anything. I did it like that but turns out “Layer Collision Settings” or even layers aren’t included into unitypackages. I’ll (hopefully) fix it in a few hours.

02.08.2016 – v1.1: Download PokemonGO Clone Part 3: Dynamic Tile Loader
-Fixed central tile collider problem by replacing it with a Rect

47 thoughts on “PokemonGo clone using Mapzen – Part 3: Dynamic Tile Loader

  1. Taking into account the speed of movement of the person has to be perfect . How to implement a ” GPS location ” ? Once the coordinates of the character is not tied to Lat – Lon coordinates. Sorry my bad English.

    1. I haven’t looked into the GPS stuff yet but I believe it should go something like;
      1)Query Unity3d LocationInfo class for Lat/Long
      2)Convert it to meters (in Mercator), subtract central tile position (in meters) from that. This should yield the player position in unity space.
      3)Lerp player character to that point
      4)Wait for a few seconds and go to (1)

      1. ” haven’t looked into the GPS stuff yet but I believe it should go something like;
        1)Query Unity3d LocationInfo class for Lat/Long
        2)Convert it to meters (in Mercator), subtract central tile position (in meters) from that. This should yield the player position in unity space.
        3)Lerp player character to that point
        4)Wait for a few seconds and go to (1)”

        Hi great work with the stuff that you are doing, congrats on your new job, hope you are doing fine, just wanted to know how to find the central tile as you mention, is there a script object, or is there more code that i need to write?

        1. Thanks a lot!
          You can find central tile information under TileManager (and derived classes). Tile manager has CenterTms and CenterInMercator for example but they are protected so you’ll have to make them public or add support functions if you want to use them from outside.

      2. Hey,

        I know this is an old post, but I’m kinda stuck on this part. I want to retrieve long/latitudes of GameObjects so I can reposition them to the right tile/unityposition when changing zoomlevels. You’re saying this should be done by “querying the LocationInfo class”. I see the Unity class, but not sure what you mean in how to use this.

        How would I go about doing this?

        Thanks

        1. Hey,
          I’m afraid I don’t remember much about these stuff anymore πŸ™
          Have you tried Mapbox SDK though? You’ll probably find it much easier to work with. It’s a more complete solution and supported much better of course.

  2. Yo, man, you’re cool.

    But please create a git repository and host it somewhere (either Github or Bitbucket), keeping track of all the packages you created is not a pleasant task.

    Thanks for your work!

    1. Hey, thanks man!
      I’ll definitely do that, it’s getting quite painful for me as well. I’ll post it here asap. Cheers!

  3. Hey! I was wondering if you knew a way to track how many kilometers/miles the player has moved on the map?
    I’m guessing it the data would be needed from the map provider?

    1. Hey man,
      That should be easy, no need for extra data at all. All I’ll do is track gameobject movement (in 3d world unit) and convert it to km or whatever depending on the current detail level. I’ll have to figure out that last part (conversion function) but shouldn’t be a trouble.
      I also created an issue for it here; https://github.com/brnkhy/MapzenGo/issues/6

  4. And oh, this might be an annoying question, but do you plan on smoothing out the roads? Sometimes when the road is curved, you can see that the quads make up small spaces between eachother. I’m really interested in this project, really great work!

    1. I haven’t tested it on mobile and not aiming for that for now. First of all, it should be quite heavy for mobile as every single building is a seperate gameobject. Should merge them into single one for mobile really.
      Aaaand I craeted an issues for that here; https://github.com/brnkhy/MapzenGo/issues/8
      Let’s start with that and I’ll move on for other movile compatibility stuff later on.

  5. hi…sorry for my english.you are doing a great work….really….im learning with it.but i think i found a problem….long and lat on mapzen loaded image is not the same as osm image…..im doing something wrong?are the coordinates moved??

  6. Been playing about with your project for the past week and have added boundaries and water.

    Couple of issues I can’t work out though, water seems to contain 4 types of data structures. LineString, MultiLineString, Polygon and MultiPolygon. While the polgon types are straight forward, the LineStrings are a nuisance. I have found that some actually duplicate the location of the polygon information and the MultiLineString makes empty spaces, as in traces the outline of an area. I think you could possibly close the loop on the string by turning it into a polygon if you line up the close on the edge of the tile. Not too sure though?

    Boundaries was straight forward however I did come across some areas, though very rare, the normals are flipped, I had to create a double sided shader to render both sides of the poly for it to be visible top down and there doesn’t appear to be anything in the geo data to work from. I know it will likely come down to the winding order of when creating the mesh, but still annoying. Double sided shader/material easily fixes it though.

    Another issue I had which someone mentioned above is the float precision. I can’t change the detail level from 16. Any lower or higher and it craps out πŸ™

    1. Hey man!
      First of all, that last thing should be solved now (not tested extensively but still) if you check the latest version from my git page (https://github.com/brnkhy/MapzenGo).

      I’m also working on water layer at the moment. It’s kinda tricky. I don’t know why but I’ve totally ignored Multi/LineStrings since I started this project.
      Other than that, there are two core issues, for all layers really; (1) triangulation code fails occasionally, (2) I haven’t looked into polygons with holes yet (building with holes, water with islands etc). You can also check those stuff from “dev” branch (on git), I’ll push it on main once I’m happy with it.

      I haven’t looked into the boundaries but I also noticed occasional flipped buildings in the past. I believe it might be related to two problems I noted above, triangulator errors or result of not caring about hole (if I recall correctly, holes are represented with counter clockwise (or clockwise? cant remember) polygons.

      Thanks for the feedback!

      1. haha awesome! Great work so far though! I actually have implemented a basic GPS Manager too along with calculating distance traversed using Haversine formula. Quite good fun already seeing it working on my Samsung Galaxy S6 πŸ™‚

        Oh with the boundaries when you start playing about with it, one thing to note is your method of the unique id will not work in some instances. Some boundaries share/occupy the exact same space. For instance, a woodland would have same geo coordinates as a national park. I changed the key to a string for now using X_Y_Z_Type just so I could see it working with all boundaries.

        Oh and I mean landuse instead of boundaries… not sure where I got that name from? Possibly Google Maps or something :S

        1. I managed to get water layer work I guess, it was an extremely small silly mistake. Now it works quite good as far as I could test.
          I knew those keys would create all sorts of problems, but it was decent for buildings I guess. Still I believe I know how to fix that, not sure if I pushed that into git or not though. There was a small problem where the json parser I’m using failed to parse ids properly. With that fixed, there is absolutely no reason not to use, unique ids mapzen provide.
          I believe mapzen also has “boundaries” layer for city, country etc boundaries πŸ™‚

    1. I’m not able to check that in Unity right now but that’s probably the intended behaviour. I might be wrong but blue point is probably the center of the current TMS tile. And red is the point you reqested. Tile manager finds the tile containing requested point, then snaps its center to 0,0 as you noted.

  7. thanks….then..the long , and lat i request, is not in the center of the tile donloaded?..just a tile with the point in it, the center is not the point i request?…is that?

  8. thanks brnkhy, i undertand it now….and great work again….thank you very much….i keep learning with you and your project….

    1. Hey Ronald, thanks man!
      You can change the starting lat/long from “World” object in the scene. There is a script also named “World” there, which holds the Lat/Long parameter. Just change them with whatever lat/long newyork is and hit run! πŸ™‚

        1. It’s working man. i changed the long/lat in the Monodevelop but it didn’t work then I realized that in the hierarchy there is also an World object that holds long/lat parameters XD sorry still newbie for unity. by the way thanks for this tutorial it really helps me. hope you can publish it on android πŸ˜€

  9. I tried to copy the project, but for some reason, some of the roads go up off the ground, or down through it, is that something you know about?

  10. hi, i kept getting an error in editor which says
    error CS0176: Static member `UniRx.MainThreadDispatcher.StartCoroutine(System.Collections.IEnumerator)’ cannot be accessed with an instance reference, qualify it with a type name instead

    not sure wats happening, im using unity 5.5 btw
    i opened an issue in github already
    thx for sharing this, awesome work!

    1. Hey there!
      I updated the UniRx and package 8.6 above. Can you tried it out and let me know if it’s working for you now?

    1. Hey sorry for the late response (gdc rush ><). All those stuff should be under TileManager classes (and classes inherited fro that), have you checked those?

Leave a Reply