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;
- 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)
- 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) - 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! - 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?
- 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).
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
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.
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)
” 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?
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.
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
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.
very helpful! You will use the GPS positioning?
Thanks! I’ll do a post on GPS, probably next week (or maybe this weekend).
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!
Hey, thanks man!
I’ll definitely do that, it’s getting quite painful for me as well. I’ll post it here asap. Cheers!
Done!
https://github.com/brnkhy/MapzenGo
I’ll announce it in the next post as well, but until then…
Please do let me know if everything works fine.
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?
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
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!
Yes I’ll definitely do that as well, created an issue here; https://github.com/brnkhy/MapzenGo/issues/7
It won’t be perfect though, as Mapzen data doesn’t have the concept of intersections. But curves will be there no problem.
Could not work on android mobile for the version built by Unity3D?
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.
float is limited to 7 characters long (((
Most inaccuracy obtained
The gaps between the tiles (
612 and 611.5
Hey man!
You’re absolutely right on that! I thought it was good enough so didn’t bothered to fix that but yea, gotta do it properly I guess.
There we go; https://github.com/brnkhy/MapzenGo/issues/9
The distance between the tiles and the texture map. Especially scale 18. (
“Load image” checked
Hmm it works fine for me using the latest version here; https://github.com/brnkhy/MapzenGo
Guess it’s fixed after that last bug fixes, can you try that please?
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??
I’m using OpenStreetMap image service in my project already. Can you pull and try the latest version from my Git page please?
https://github.com/brnkhy/MapzenGo
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 🙁
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!
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
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 🙂
Will definitely check it out later tonight 🙂
Ah that might be where I saw the boundaries then, I think when I went to implement it before I assumed boundaries marked out land use and probably got the name still stuck in my head from that.
Thought I would share this page I came across too: http://www.macwright.org/2015/03/23/geojson-second-bite.html
Hello
This is another map visualistation projekt on unity3D
https://github.com/reinterpretcat/utymap
That looks quite nice indeed!
hi..i use the last one on github……..please..see that image…thats the problem i see
https://dl.dropboxusercontent.com/u/43145096/mapzen.jpg
maybe im doing something wrong……
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.
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?
Yes absolutely. You can check it here;
http://oms.wff.ch/calc.php?baseurl=openseamap&lat=43.36241&long=-5.86294&longto=0.000000&latto=0.000000
I believe you’re using detail level 16 and the center of that image matches the blue point you posted earlier.
thanks brnkhy, i undertand it now….and great work again….thank you very much….i keep learning with you and your project….
You’re welcome Kano, I’m glad you like it 🙂
Great work man! Can you tell what part can I change to spawn ethan in a different location. Like I want him in New York. Thank you by the way bro. Appreciate your work 😀
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! 🙂
Thank you for your response man 😀 I already tried that one but it still at the same location XD
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 😀
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?
Hey Jeppe,
I haven’t seen something like that before, can you post a screenshot or something?
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!
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?
Hi man! Nice posts, i’ve one question: How can i load more than 9 tiles?
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?