Search Unity

World map and 3D view coordination.

Discussion in 'Getting Started' started by TheCandy, Dec 5, 2016.

  1. TheCandy

    TheCandy

    Joined:
    Dec 5, 2016
    Posts:
    22
    Hello,

    I am making a naval game (PC only) and i would like to have rather large (~1000km x 1000km) fictional "caribbean sea"-like area with some islands. I have the ship model, controls and "physics", but I would like to know a few things...

    Currently I am using a sea mesh, which is following the boat and is large just enough for player to not see the edge. Every boat on this mesh is bouncing up and down according to sea waves. There are islands on fixed positions on the map and player simply sails with the sea mesh to the islands.

    1) How to make a world map view with players position and other ships position in players area with smooth transition (not switching to a different scene)? One thing comes to my mind - having a plane with same dimensions as the world itself and a orthographic camera watching this world and showing the positions based on the coordinates of the boat. But I guess that this solution is not very smart and pretty heavy.

    Other solution would be a different scene for the world map and sharing the coordinates with the 3D scene to spawn the models in 3D / spawn sprites on 2D.

    2) Is it a good idea to have all the islands on the same map in the same scene? I would like to have rather large and detailed islands - roads, buildings, few ports... Should I use different scenes for map "tiles", or is it fine to use one huge map? Ive heard, that the only things rendered are the ones that the currently used camera can see - if this is true, I could make one huge map, right?

    Other solution, that i can think of, would be using ~ 5km x 5km tiles and putting, lets say, 9 of them on the map with the center one in 0x0x0 coordinates. As the player crosses the tile at the border, the tile on the other side would become the center one and all the coordinates would recalculate..

    These 5kmx5km tiles would be prefabs. For 1000km x 1000km map, that would require 40 000 tiles, but as most of the map is water, we can use prefabs only for islands and shallow waters, reducing prefab count drastically.

    example: Player is in the center of the map. He travels only on the z coordinate to the north. If he reaches the z at 2500, he is teleported to z = -2500 and all the objects are teleported to a new z coordinate = ("z coordinate before" - 2500) and the northern tile is moved to the 0,0,0 , becoming the center one. Three tiles at the south are discarded and three tiles at the top are spawned according to some matrix that stores neigbouring tiles info.

    New coordinate calculations would go like this:
    If |player_x_coordinate|=2500 then player_x_coordinate = inverse value of player_x_coordinate , z_coordinate stays the same.
    All other object x_coordinate = x_coordinate - player_x_coordinate (- & - = + )
    .... same goes for the case that player hits max z coordinate first.

    Map view would be on the same scene and would move icons like: current tile => coordinates on that tile

    Feel free to share any concern or issue that would come to your mind. Thanks
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    You're on the right track with the recentering. Without doing that, you will run into floating-point errors on a map that big when you get far from the origin. So, recentering is pretty much a must.

    But I like your current sea mesh that travels with the player. Done right, that sounds like it's absolutely the most efficient way of modeling the ocean. So you have islands floating in a vast nothingness, and water that travels around you so you never suspect this.

    It's true that objects outside the camera view are generally culled, but that doesn't mean they're free. They will still process scripts etc. unless you deactivate them. And they'll take up memory even if they're deactivated.

    I would suggest setting aside a week to do some performance tests. Write some quick test scripts that populate your world with more islands than you think you'll have, and see what sort of frame rate you're getting. If it's fine, then you don't need to get fancy with deactivating or destroying things that are far away. If not, then you'll need to invest in that extra island management.

    EDIT: Oh yeah, and the world map, I'd just do that in 2D. Either with sprites, or with UI.
     
  3. TheCandy

    TheCandy

    Joined:
    Dec 5, 2016
    Posts:
    22
    I ran into a problem.... When using the code:
    If |player_x_coordinate|=2500 then player_x_coordinate = inverse value of player_x_coordinate

    i ran into a problem: x never gets exactly to 2500 when moving... i tried > instead of ==, but the boat goes to ~2505, before the code teleports it....

    it seems like a minor issue, but when calculating the location for the map icon, things get really messed up
     
  4. TheCandy

    TheCandy

    Joined:
    Dec 5, 2016
    Posts:
    22
    Problem solved.....

    To elaborate...

    Best solution for the map I can think of is icon, which is moving 1/1000 of unit (1mm) for every unit (1m) that boat moves.
    This gives fine resolution and means that map scale will be 1000x1000 units or 1km², which is not too much, I guess.

    The only problem is the "teleporting", which is solved by "tile coordinates", as the world is made from 200x200 tiles, each 25km² .. center tile is at 0,0

    The icon is sharing boat coordinates, but both of them go like: icon.x = boat.x / 1000 + tile coordinate * "modifier"
    Modifier is there to decide how much to add to the icon coordinate, when boat crosses the border, that means when the tile is 5000m across, you add (5 metres * current tile coordinate) to the icon coordinates..... phew....



    Now to the solved issue.... i was using a "cooldown" to prevent the boat from not that rare glitching, when the code decided to teleport the boat between +2500 and -2500 indefinitely. I simply added a one second cooldown

    private float cooldownStart = 0f;
    private float Cooldown = 1f;

    if (Time.time > cooldownStart + Cooldown)

    {
    // coordinates check code

    cooldownStart = Time.time;
    }


    This caused the problem with the "not so accurate" coordinates.
     
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I think that cooldown is likely to cause other problems too, not just this one. I'd encourage you to find a different approach.

    You should pay attention to what way your boat is moving, and only teleport it when it's over the border and continuing in the outside direction. That will eliminate the back and forth teleporting without needing any cooldown.

    Or, if it works with your setup, add a bit of border buffer. So when x >= 2501, you subtract 5000 (which puts you around -2499. And when x <= -2501, you add 5000 (putting you around 2499). Again, no possibility of ringing, and no cooldown needed.
     
  6. TheCandy

    TheCandy

    Joined:
    Dec 5, 2016
    Posts:
    22
    And do you think that my solution of the map => 1000x1000 tile with sprites with scaled down movement of the real objects and a huge scrollable camera is a good approach?

    Thank you for your amazing input and incredible understanding of my chaotic explanations.
     
  7. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Actually, you give me too much credit — I have not, in fact, understood much of your chaotic explanations. :)

    I think you're going to have a lot of grief trying to do the map with sprites, using the same camera that shows the 3D world. If that's what you're doing, you have certainly chosen the way of pain.

    If you want to use sprites, then make a second camera, which stays put in one place, orthographic mode. Layer it to always draw after (on top of) the 3D camera. And then you can put sprites in front of it, and have a poor man's UI.

    Or, you could use the actual UI features built into the engine. That's good too. :)
     
  8. TheCandy

    TheCandy

    Joined:
    Dec 5, 2016
    Posts:
    22
    The camera watching the map is the different than the one watching the 3D scene. It is orthographic and its culling mask is set to the "mapstuff" layer. Then i simply switch between them by enabling / disabling the other camera.

    My main concern was to display the icons on rather small map plane, but still big enough to be able to scroll very closely and see the movement of the icons in detail.
     
  9. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Ah, good. I misunderstood what you were doing. That sounds like that should work.

    OK. Not quite following the problem there, but clearly you do, and that's what matters!