PokemonGo clone using Mapzen – Part 1: Basics

So my last post from 2014 December kinda exploded after the PokemonGo craziness and I decided to fix&improve it further. I’ll try to make a little blog post series on this one, starting with fixing/refactoring the old sample and then moving further and adding character movement, dynamic tile loader etc etc. I’m planning to have a proper Go clone when I’m done.

I’ll keep the post short as it’s quite time-consuming for me to write these as I’m still not feeling that comfortable writing in english (it’ll get there) but I’ll try to explain what’s going on as much as I can. But before we start, especially if you haven’t seen the old post, OpenStreetMap in Unity3D, I suggest checking that out first. It’ll be much easier/clear after that.

So first of all, you can get it here; PokemonGo clone – Mapzen sample and I’ll try to explain going over that here. Now extract the package, open scene file “BasicLoader” and run it.

PokemonGo clone

You should get something like this. Well it’s looks kinda ugly yea, but we’ll go into technical stuff before eye candy.

There are two gameobjects in the scene,
First one is the camera, which is pretty much standard camera with just one script (StrateCam) attached. It’s a quite handy little Orbit / RTS cam script.
Second one is “World” and that’s where all the magic happens.

Actually World script is just an entry / interface script. There is no logic or anything behind it, it’s just a container and starting point for the real thing; “TileManager”.

TileManager is the script responsible for handling everything about TMS tiles. For now, it just loads and created tiles but in the future posts, we’ll do a lot more here, like dynamically loading/destroy tiles depending on player position etc.

Tile script does pretty much everything (that sounds quite wrong, I know. Might refactor that later). It loads the data (this should be a service, bad idea doing it here), creates tile and uses BuildingFactory and RoadFactory classes to create building and road meshes/gameobjects respectively. As I said I’ll probably do some refactoring here but it’s quite straight forward for now. Load Data, create tile, load map image if necessary, create buildings create roads.

BuildingFactory and RoadFactory, are two simple factories for creating meshes and gameobjects given json objects and a relative position (owner tile center). We’ll add extra stuff like, fancy building model construction or curvy roads here. There are also some temporary (read wrong) stuff in there like using the first corner of a building/road as a unique identifier. Yes it’s wrong but somehow I couldn’t get Mapzen id’s to work for me couldn’t get my json parser to parse id’s properly , I’ll look into that later on as well.

And that’s pretty much it! Quite simple for now but I’ll be adding much more soon. Character movement and dynamic tile handling should be next two big things.

Hope you guys like it, let me know if you have any questions or whatever (I’ll be playing PokemonGo around),
Cheers, Baran

Download PokemonGO Clone using Mapzen Api Project

 

 

 

34 thoughts on “PokemonGo clone using Mapzen – Part 1: Basics

  1. Hello,

    You did an amazing work! It works really well.

    I work around your code today and I was able to get every crossroads (for making a traffic system) and to load tiles dynamicly.
    I would like to know, before continuing my project, if we’re allowed to use parts of your code for our projects or not?

    1. Hey Leo!
      I’m glad that it worked without any issues and you liked it! I’m already (almost) ready for the second post and I’ll try to wrap it around in a few days (writing the post is really the hardest part).
      You can use it anyway you want, anywhere you want. So legally speaking, it’s pretty much WTFPL license (http://www.wtfpl.net).

    1. Hey,
      Any chance you forgot to open “BasicLoader” scene? It’s inside the “Scenes” folder, just double click and you’ll see some new stuff in the “Hierarchy” panel on the left side.
      Then hit run and it should load everything. If not, there might be a problem with your internet connection as it pulls everything from Mapzen servers. No data, no tiles 🙁

        1. Hey Pawel, sorry for the late response.
          I have no idea admittedly. I’ll try to look into it after the 3rd part but I guess the scenario files from latest version simply isn’t compatible with 4.6.2.
          You don’t need the scene file though, as it’s empty anyway. All you need is World, TileManager, BuildingFactory (as child of TileManager), RoadFactory (as child of TileManager) scripts if I recall correctly.

  2. Thnx, that was the problem. Now I have some CORS issues, because mapzen doesn’t have a crossdomain.xml hosted and the webplayer needs it I guess. I am using latest unity in windows 10.

    Is building for the web player, the same is building an swf file or?

    1. Hmm I have no idea about the CORS thing, never tried this on webplayer before.
      But that’s pretty much an isolated issue, you can either fix the api calls with something playing along cross domain calls OR (if you dont need the whole world) can cache the tile data and load from file.

    1. Hye Pimenov!
      You’re quite right actually and that’s only because I forgot some leftover code in the BuildingPolygon class. At the moment, it’s actually creating 3D buildings but with 0 height. So given a rectangular building, one roof and four sides, that makes 8 vertices and 10 triangles. So that’s it. Code is broken though, even if you fix the height parameter. I already fixed that and will post it in a few days.
      Thanks!

      1. Hi again 🙂 Few minutes ago I look closer and found a mistake, i fix it by replacing your

        private static Mesh CreateMesh(List verts)

        method with mine, now it works fine,

        private Mesh MyMeshCreating(List verts)
        {

        var tris = new Triangulator(verts.Select(x => x.ToVector2xz()).ToArray());
        int[] indices = tris.Triangulate();
        Vector3[] vertices = new Vector3[verts.Count];
        for (int i = 0; i < vertices.Length; i++)
        {
        vertices[i] = new Vector3(verts[i].x, 0, verts[i].z);
        }

        Mesh msh = new Mesh();
        msh.vertices = vertices;
        msh.triangles = indices;
        msh.RecalculateNormals();
        msh.RecalculateBounds();

        return msh;
        }

          1. It’s perfect!!! Thank you very much! I’m just new with 3d, all times before I just work with 2d games, and it’s very interesting for me now!

  3. Thanks for putting this together, but after importing the package into an empty project and running the BasicLoader scene I get the following two errors:

    AddComponent with MonoBehaviour is not allowed. Create a class that derives from MonoBehaviour and add it instead.
    UnityEngine.GameObject:AddComponent()
    Assets.Helpers.CoroutineStarter:.cctor() (at Assets/Helpers/CoroutineStarter.cs:32)
    Assets.TileManager:Init(BuildingFactory, RoadFactory, Settings) (at Assets/Models/TileManager.cs:53)
    Assets.TileManager:Init(BuildingFactory, RoadFactory, Settings) (at Assets/Models/TileManager.cs:50)
    World:Start() (at Assets/Models/World.cs:24)

    NullReferenceException: Object reference not set to an instance of an object
    Assets.Helpers.CoroutineStarter..cctor () (at Assets/Helpers/CoroutineStarter.cs:33)
    Rethrow as TypeInitializationException: An exception was thrown by the type initializer for Assets.Helpers.CoroutineStarter
    Assets.TileManager.Init (Assets.Models.Factories.BuildingFactory buildingFactory, Assets.Models.Factories.RoadFactory roadFactory, .Settings settings) (at Assets/Models/TileManager.cs:50)
    World.Start () (at Assets/Models/World.cs:24)

    It compiles fine but throws these runtime errors. Any suggestions?

    Thanks,
    Chris

    1. Hey!
      That’s interesting. Have you tried the new version in the third post? If I recall correctly, I removed CoroutineStarter class there.

  4. Great work bro 😀 im working for our game development subject so I can graduate for college. We are replicating the game pokemon go also. can you tell how to change the location?

  5. I get an .tar file when I extract the project sample. when I extract it again it cointains folders with random numbers. need help pls im really new to this. thanks

    1. Hmm I guess you’re trying to unzip the unitypackage file? That won’t work, just open an empty project in unity and import the packagefile, it’ll extract everything automatically 😉

  6. Hi, Brnkhy
    I run into the following issues( Unity 5.4.2):

    AddComponent with MonoBehaviour is not allowed. Create a class that derives from MonoBehaviour and add it instead.
    UnityEngine.GameObject:AddComponent()
    Assets.Helpers.CoroutineStarter:.cctor() (at Assets/Helpers/CoroutineStarter.cs:32)
    Assets.TileManager:Init(BuildingFactory, RoadFactory, Settings) (at Assets/Models/TileManager.cs:53)
    Assets.TileManager:Init(BuildingFactory, RoadFactory, Settings) (at Assets/Models/TileManager.cs:50)
    World:Start() (at Assets/Models/World.cs:24)

    NullReferenceException: Object reference not set to an instance of an object
    Assets.Helpers.CoroutineStarter..cctor () (at Assets/Helpers/CoroutineStarter.cs:33)
    Rethrow as TypeInitializationException: An exception was thrown by the type initializer for Assets.Helpers.CoroutineStarter
    Assets.TileManager.Init (Assets.Models.Factories.BuildingFactory buildingFactory, Assets.Models.Factories.RoadFactory roadFactory, .Settings settings) (at Assets/Models/TileManager.cs:50)
    World.Start () (at Assets/Models/World.cs:24)

    anything I missed?

    1. Hey Wensi,
      I thought I removed CoroutineStarter from project long long ago. Which version are you using? I’ll try to check this asap. Thanks!

  7. Hello BRNKHY,

    I got error on –

    UniRx.MainThreadDispatcher.StartCoroutine (IEnumerator routine) (at Assets/Plugins/UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs:367)

    1. Hey Romit!
      It was an error with old UniRx package. I updated the UniRx and uploaded the new package. Can you please try that one and let me know if everything is alright?

      1. I have the same problem:

        AddComponent with MonoBehaviour is not allowed. Create a class that derives from MonoBehaviour and add it instead.
        UnityEngine.GameObject:AddComponent()
        Assets.Helpers.CoroutineStarter:.cctor() (at Assets/Helpers/CoroutineStarter.cs:32)

        NullReferenceException: Object reference not set to an instance of an object
        Assets.Helpers.CoroutineStarter..cctor () (at Assets/Helpers/CoroutineStarter.cs:33)

  8. Good day sir? Can I change the location with my current location and move like in pokemon go that will only move if the location of the mobile with that application is moved?

Leave a Reply