Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Grids Pro: A library for hex, tri, polar and rect grids [New Dcoumentation for Grids 2]

Discussion in 'Assets and Asset Store' started by Herman-Tulleken, Jul 10, 2013.

  1. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Last edited: Jun 29, 2017
  2. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    847
    Does it support different heights for 3D maps as well, or would they need to be flat?
     
  3. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Edit: After writing the long post below I realised there is also a much easier way to do it, and that is simply to use the normal XY map and then use the height as needed (making a new vector from the old "flat" one and the height). The below is still useful for something more generic.

    -----

    It can handle different heights quite easily, although you need to figure out how to get the height somehow (raycast, array of heights, whatever).

    You do need to implement your own version of the 3D map (maps are the things that translates between grid coordinates and world coordinates - you can read a bit more on it here: http://gamelogic.co.za/grids/quick-start-tutorial/working-with-maps/). The advantage of keeping this logic separate is of course that once you have wirtten it, you can use it with all the grids.

    Say you have a function that gives you the terrain height for a given coordinate:

    Code (csharp):
    1. float GetTerrainHeight(Vector2 coordinate){...}
    Then you can implement your map very similar to the XY plane map code that comes with the library, like this:

    Code (csharp):
    1. public class Map3DXYTerrainHeight<TPoint> : IMap3D<TPoint>
    2.     where TPoint : IGridPoint<TPoint>
    3. {
    4.     private IMap<TPoint> map2D;
    5.  
    6.     public Vector3 this[TPoint point]
    7.     {
    8.         get
    9.         {
    10.             Vector2 point2D = map2D[point];
    11.             float z = GetTerrainHeight(point2D);
    12.  
    13.             return new Vector3(point2D.x, point2D.y, z);
    14.         }
    15.     }
    16.  
    17.     public TPoint this[Vector3 point]
    18.     {
    19.         get
    20.         {
    21.             // Use the 2D projection, ignore height.
    22.             // (You could do something different here)
    23.             Vector2 point2D = new Vector2(point.x, point.y);
    24.  
    25.             return map2D[point2D];
    26.         }
    27.     }
    28.  
    29.     public Map3DXY(IMap<TPoint> map2D)
    30.     {
    31.         this.map2D = map2D;
    32.     }
    33. }
    Then all you have to do is provide an extension method to the IMap interface to add your map:

    Code (csharp):
    1. public static class MapExtensions
    2. {
    3.     public static IMap3D<TPoint> To3DXYTerrainHeight<TPoint>(this IMap<TPoint> map)
    4.         where TPoint : IGridPoint<TPoint>
    5.     {
    6.         return new Map3DXYTerrainHeightMap<TPoint>(this);
    7.     }
    8. }
    9.  
    Then you can use it with any grid just like any of the standard maps. For instance, if you have a hex grid with cells 7 by 6 unity units, you can define your grid and map like this:

    Code (csharp):
    1. var grid = PointyHexGrid<bool>.Hexagon(10);
    2. IMap3D<PointyHexPoint> map = new PointyHexMap(new Vector(7, 6))
    3.    .To3DXYTerrainHeightMap();
    4.  
    Now you can use the map to convert between grid points and world points, taking the correct terrain height from your function (behind the scenes).

    You can now, for example, spawn items in the world where corresponding grid values are tru, like this:

    Code (csharp):
    1. foreach (var point in grid)
    2. {
    3.    if(grid[point])
    4.    {
    5.       var newItem = (GameObject) Instantiate(itemPrefab);
    6.       newItem.transform.position = map[point] //the map converts the grid point to world point with the right height
    7.    }
    8. }
     
    Last edited: Jul 19, 2013
  4. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    847
    Nice. I think I will give this one a try after my next paycheck. :)
     
  5. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Cool :) Let us know what you think, and don't hesitate to drop us a mail if you have trouble.
     
  6. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    847
    So, gave in and bought Grids from the asset store, currently busy rewriting the LightsOut example into another simple game. Mechanics are already in place and extending the provided prefabs was a bliss so far.

    Is there an easy way to find the cell that is most left/right/upper left/etc. in a grid? I would like to provide starting points for two or more players on opposing ends of a grid without doing it manually to support different grid sizes out of the box.
     
    Last edited: Jul 26, 2013
  7. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hey c-Row. Thanks for giving it a try :)

    Unfortunately, there is no one-method call to do it. One reason we did not include it is becuase it is not always clear what the top-left corner should be.

    For instance, in the shape below, a case could be made that either of the 0s is the top-left corner:

    Code (csharp):
    1.  0 x x x x x x
    2. 0 x x x x x x x
    3.  x x x x x x x
    4. x x x x x x x x
    However, it is fairly easy to implement. Here is an example for hex points:

    Code (csharp):
    1. int topRow = grid.Max(point => point.Y);
    2.  
    3. int topLeftX = grid.Where(point => point.Y == topRow).Min(point => point.X);
    4. int topRightX = grid.Where(point => point.Y == topRow).Max(point => point.X);
    5.  
    6. PointyHexPoint topLeft = new PointyHexPoint(topLeftX, topRow);
    7. PointyHexPoint topRight = new PointyHexPoint(topRightX, topRow);
    8.  
    9. int bottomRow = grid.Min(point => point.Y);
    10.  
    11. int bottomLeftX = grid.Where(point => point.Y == bottomRow).Min(point => point.X);
    12. int bottomRightX = grid.Where(point => point.Y == bottomRow).Max(point => point.X);
    13.  
    14. PointyHexPoint bottomLeft = new PointyHexPoint(topLeftX, bottomRow);
    15. PointyHexPoint bottomRight = new PointyHexPoint(topRightX, bottomRow);
    This code selects to top / bottom rows first, and from there the left and rightmost points in each row.

    (It should be an easy switch to do rows first then columns).

    Let me know if this helps you out.
     
    Last edited: Jul 27, 2013
    Aggressor likes this.
  8. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    847
    Only was able to put in a few minutes every now and then, but this is what I've got so far. It's a game in which every player places a single atom in one of the cells he already owns. Once the number of atoms exceeds the available space they are distributed to the adjacent cells, preferably taking over enemy cells in the process. Once a player has lost all his cells, the game is over.

    [ Webplayer ]

    Adapting the Lights Off example proved rather easy, and there are enough built-in functions to take care of things. Oh, and I learned some things about implementing player turn mechanics in the process as well. ;) The game isn't quite completed, but the things missing at the moment aren't directly related to Grids.

    So far I can fully recommend this asset. :)
     

    Attached Files:

  9. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hi c-Row

    Glad to hear it's going well so far :) My love for abstract puzzle-play is one of the motivations behind the library, so am very keen to see where you take your interesting mechanics!
     
  10. Robin_B

    Robin_B

    Joined:
    Aug 5, 2013
    Posts:
    2
    Hi! I'm prototyping a simulation game based on a hex grid, so your asset looks quite interesting. So now I'm two minds if I should roll my own version -- I'd certainly know how to do it, but not sure if it's worth it. How efficient is your pathfinding algorithm? I assume it's using A*? How easy do you think would it be for me to multi-thread your pathfinding? My game will depend on that a lot, so I'm considering having a background path-finding thread where I queue up the pathfinding requests...
     
  11. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hi Robin_B,

    Our path-finding is indeed using A*. I thought of ways in which we could make the algorithm threadable when we implemented it, but it seemed to me to be somewhat game specific problem, because of the various factors involved, (for instance, does the map update? how many moving agents are there? how much path information does each consume at a time, etc.) so solving this problem in a generic way seemed to be a good project in itself.

    Our implementation is straight-forward, certainly not rigorously optimised. However, this may make it easier to adapt for your needs.

    I will PM you the core functions of the path finding if you want to examine them a bit to help you decide if it would be worth your while (at least, as far as path-finding is concerned; grids obviously provide more functionality than this).
     
  12. Jonathan-Bailey

    Jonathan-Bailey

    Joined:
    Aug 12, 2013
    Posts:
    79
    Hi Everyone,

    My name is Jonathan, I make up the other half of Gamelogic.

    We have finished our first video for Grids which shows some of the main features and some of the examples that are included. Check it out in the first post in this thread.

    Also check out some of the new examples on our website (note that you need Unity Web Player to run them):

    $cairo_grid_lights_out.png
    Here is an image of Lights Out on a Cairo Grid
     
  13. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    We have made two new updates since the first release, adding more juice to the library and making sure bugs get eliminated fast. Here is what is new:

    Version 1.1

    • Added grouping for shape building.
    • Added symmetric difference for shape building.
    • Added more parallelograms for triangular grids.
    • Changed the diamond grid / point coordinate system to be more intuitive.
    • Fixed a bug with hexagonal shapes for triangular grids.
    • Fixed a bug with composite shape building.
    • Fixed a bug with vertex and edge grids.
    • We also added an example that shows advanced shape building.

    Version 1.2

    • Added PolygonMap for handling general polygon-grids.
    • Added CairoMap, CairoGrid and CairoPoint as an example of an "exotic" grid.
    • We also added two more examples: one shows how to set up the Cairo grid; the other is the Lights Out game on a Cairo grid.

    Throughout, we also improved documentation, and the code and presentation of the examples.

    $cairotype.png
     
  14. Play_Edu

    Play_Edu

    Joined:
    Jun 10, 2012
    Posts:
    722
  15. Jonathan-Bailey

    Jonathan-Bailey

    Joined:
    Aug 12, 2013
    Posts:
    79
    Hi Play_Edu,

    yes you can do animated effects like that. Maps make it very easy to animate grids.

    All of the effects in our video have been made with our grid library in Unity. If you haven't already seen it, you can view the video at the top of this thread or on our website.
     
  16. Play_Edu

    Play_Edu

    Joined:
    Jun 10, 2012
    Posts:
    722
    Thank you for replay.
     
  17. tin2tin

    tin2tin

    Joined:
    Aug 22, 2013
    Posts:
    12
    Hi,
    Is every cell a game object? Or I can make whole map one game object and only use location data to distinguish cells?
    Could you make a stress test demo (web player or video)? Curious how your solution performs for huge map? (say 500x500 PointyHex Grids)

    Thanks.
     
  18. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hey tin2tin,

    Cells can be game objects, but they need not be. Grids work like 2D arrays, and can contain anything. And indeed, you can have your map as a single image. The grid-setup examples that comes with the package has a plane in the background that is colored with the same colors as the actual grid; a similar method can be used if you represent your world as a single game object.

    Grids perform well even when they contain many game objects. Here is an example with 250 000 hexes:

    http://gamelogic.co.za/250-000-hexes/
    (You can also see the code there).

    (Use the arrows to move, and the mouse to toggle hexes on or off).

    In this example, actual 3D meshes are instantiated. Instantiation is the bottleneck (not any grid calculations), so I put that in a co-routine and generate 1000 at a time. (Even so, it only takes a few seconds). Of course, other strategies can be used for instantiation, but it's completely independent from the grid itself.

    The size of the grid does not impact performance (of course, whatever strategy you use to render the grid - using game objects, or sprites, might).

    • Mapping from screen to grid is constant time.
    • Mapping from grid to screen is constant time.
    • To determine whether a point is inside your grid (for all built-in grids and shapes) is constant time.
    • To find neighbors of a cell is constant time.

    Hope this gives you an idea of how our Grids library performs!
     
    Last edited: Aug 24, 2013
  19. tin2tin

    tin2tin

    Joined:
    Aug 22, 2013
    Posts:
    12
    Thanks Herman! That 250,000 hexes demo is imprssived.

    Do you have a roadmap of your grids library for near and future version?
     
  20. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hey tin2tin,

    Hehe it's fun making those examples :)

    We do have a roadmap, although we will keep an eye on feedback to decide how to prioritize these, and also for other opportunities to extend Grids. Here is our current list of coming features:

    • Arbitrary convex poly grid (so you can really build your own unique grids with ease). Vertex and edge support for these grids.
    • Transformations to arbitrary points (this is for special types of games using exotic coordinates such as spiral coordinates, or nested coordinates).
    • Neighborhood aggregation that treat points uniformly (instead of treating the central point as special) - useful for certain AI algorithms.
    • Neighborhood aggregation that work directly on values instead of keys (convenience).
    • State maps - to allow grids to be transitioned in and out, for instance, useful for nice effects, especially for unique interface building.
    • Blend map - to allow you to quickly transition from one map to another (also for transition effects).
    • More powerful animation map (that can be controlled more intuitively, and is not driven by Time.time, but by arbitrary means).
    • More features for dealing with shapes spanning multiple cells in a grid - for building interesting irregular grids, handling things such as block-puzzles (slide puzzles, shape-fill puzzles) in grids better.
    • Warped grids. (Just need new neighbors, new map[?]) - out the one end, in the other
    • For shape building: 2-, 3- and 6- fold symmetry operations (rotate and duplicate) to make it even easier to build custom shapes.
    • More algorithms: line of sight, snapping, sliding, etc.
    • 3D terrain and mesh maps - basically adding more ways to handle the height in 3D out of the box.

    One thing we are also looking at is providing better means to handle animation of cells when changing grid cells. This is mostly relevant to 2D games, and we are not sure what the solution will be. (It is not really part of the grid per se, but we feel it's important to have a ready solution, so that it makes it easier to polish your game that uses Grids).

    We are also looking at making some tools to make it easier to make hex and other poly tiles from custom textures/designs, especially for seamless and blended tiles, and tiles made for edge or vertex matching.

    ----
    This is a bit of a vague list at this stage. As we get more user feedback, we will make it more precise. And if there are features you want but don't see, please let us know!
     
  21. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    847
    Back at Grids again for now... I wanted to see whether it was easy to get both Grids and 2D Toolkit to play along nicely to combine the former's grid logic with the latter's ease of use (sprite animations etc). Well, a few lines of code and a bit of testing later, I got a nice RectGrid to move my sprite around on. map[RectPoint] is your friend. :)

    Now off to creating some actual gameplay...
     

    Attached Files:

  22. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    847
    Seems like I am too stupid for what I am trying to do... I want to loop through all the RectPoints in a grid from an outside script but somehow can't get my head around how to access it from remote. grid and map have already been set to public.


    [edit] Nevermind - tried to access it before the grid had been built. Silly me. :rolleyes:
     
    Last edited: Sep 25, 2013
  23. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Looking cool :) We have also been playing with 2D Toolkit. One thing that's nice is the polygon collider tool, which works really well with funny shape cells. Let us know what you come up with :)
     
  24. Jonathan-Bailey

    Jonathan-Bailey

    Joined:
    Aug 12, 2013
    Posts:
    79
    New Grids Version (1.3 and 1.4), Hex Grids 1.4, 30 games in 30 days.


    We have made two more updates to the Grids library including some minor improvements, bug fixes and a few new examples. We also created a subset of the library that only includes hexagonal grids (40$) which is being sold as a separate package. Lastly, we started our 30 games in 30 days campaign!


    Grids Version 1.3

    This version contains mostly bugfixes and more examples. We

    • added geometry calculations for hex points
    • fixed wrong spelling of some methods that contains the word Middle - old methods have been made obsolete, so this change should not break your code
    • fixed a bug in one of the 3D to 2D extension methods provided for Transform.
    • made lots of small code quality improvements under the hood (including a few optimisations)
    • There are also three new examples that show how colorings work, how to use Grids in 3D games, and how Grids handles a very large hex grid.

    Grids Version 1.4

    In this version we re-organised the library slightly.


    Hex Grids 1.4

    Hex Grids is a subset of our Grids package and has been released on the Unity Asset Store for $40. It supports the full Grids library features, but is restricted to pointy and flat hexagonal grids.

    Asset Store Link
    https://www.assetstore.unity3d.com/#/content/9968


    30 games in 30 days!

    For the month of November we will be making 30 games using Grids – 1 game a day. We decided that it was time to put Grids to the test and prove the rapid iteration that we have promised that Grids can go.

    We’ll develop and publish a game on our site each day for you to check out and play. Check it out here.

    $Banner00.png
     
    Last edited: Nov 5, 2013
  25. PBDoughboyy

    PBDoughboyy

    Joined:
    Nov 1, 2013
    Posts:
    2
    Hey.

    I was checking out your addon and it looks like it might be something I might be able to use. I have some questions on the functionality though before I decide if I'm going to get it. Hopefully I can explain what I want to do clearly enough here.

    I'm trying to make a turn based game that is essentially a series of square rooms that will be arranged in a 6x6 grid. Each room in that layout will also have a 5x5 grid inside of it that players will move a set number of spaces on each turn. Obviously some spaces will be flagged for being able to move on, others not, and maybe have some special spaces too. The part that's going to be tricky is the rooms will be put down in a random order and rotation at the start of each game and there's a possibility some of them may switch places and/or rotate in the middle of the game as well. Does your addon give functionality for me to be easily path movement from one square to 4-5 squares away even when players are crossing from one room to the next? I've seen some other grid based addons that let you do movement easily enough inside a single grid, but don't have it built in where you can transition from one grid to another. Thanks!
     
  26. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    @PBDoughboyy

    I am not 100% sure I understand what you mean, but I think, yes, the library can provide you with a way to do that (although with a tiny bit of setup on your part). The one way to do it would be to define your own SuperGrid, which implements the main grid interface, and remap indices to the smaller grids. Off the top of my head, something like this:

    Code (csharp):
    1. class SuperRectGrid<TCell> : IGrid<RectPoint, TCell>
    2. {
    3.    RectGrid<RectGrid<TCell>> smallGrids;
    4.  
    5.    SuperRectGrid()
    6.    {
    7.       smallGrids = RectGrid<RectGrid<TCell>.Rectangle(5, 5);
    8.  
    9.       //can instantiate small grids if you want here, or set them with setter
    10.    }
    11.  
    12.    public SetSmallGrid(RectPoint point, grid)
    13.    {
    14.        smallGrid[point] = grid;
    15.    }
    16.  
    17.    public this[int index]
    18.    {
    19.        get
    20.        {
    21.           m = index.X / 5; //assume non-negative coordinates only
    22.           n = index.Y / 5; //ditto
    23.  
    24.           smallX = index.X % 5;
    25.           smallY = index.Y % 5;
    26.  
    27.           return smallGrids[new RectPoint(m, n)][new RectPoint(smallX, smallY)];
    28.        }
    29.  
    30.       //Define set similarly
    31.    }
    32.  
    33.    //Implement other interface methods if needed.
    34. }
    You can now use SuperGrid just like a normal grid, including the path finding algorithm we provide. You will probably define your own accessors (my through two coordinates, one for the big grid and one for the small grid).

    So not exactly out of the box, but not with too much effort.

    Is this what you meant?
     
  27. PBDoughboyy

    PBDoughboyy

    Joined:
    Nov 1, 2013
    Posts:
    2
    Thanks for the reply, I'll have to play around with what you have here and see if I can get it to work!
     
  28. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hi PBDoughboyy,

    Here is a more thorough example you can look at. It basically implements SuperGrid completely, and shows how to use two separate maps to convert from screen to grid coordinates and back. You can also use one map, but two maps give you more control. For example, I scaled the grids by different amounts, giving rise to space between the cells that makes it possible to distinguish the large and small grids.

    I also made an example showing path finding across the grids:

    $SuperGrid.png

    (You will find it after you imported the package under GamelogicGrids/Examples/Scenes/BasicSetup/SuperGrid)

    If you have Grids, you can run it:
    • Left click to insert / remove obstacles.
    • Right click to select the start node, and Right click again to select the goal node.

    The example is not perfect; you will have to play a bit with the anchoring and so on the get the centering.
     

    Attached Files:

    Last edited: Nov 3, 2013
  29. Middy

    Middy

    Joined:
    Jun 19, 2013
    Posts:
    4
  30. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hi Middy,

    We are not rendering at all - you have to use your own technique - tiles (using one of the 2D packages, or even Unity planes, or even Unity GUI), or meshes. This gives you a lot of control over the appearance of the grid. So it's all logic :)

    There is a path finding algorithm provided (A*), and other algorithms for working with lines and shapes.

    One of our examples also show how to work with cells that have connected things in them, such as the roads in your example. Our example uses lines, but the same principle applies.

    $pipes2.png

    Another example also shows how to use tiles for blended landscapes by matching vertices that may also be useful in constructing your landscape. The example below uses a tileset of 13 tiles, but of course you can also dynamically build tiles (for instance, using a technique similar to the one described here).

    $VertexMatch.png

    There are also lots of things that make geometry easier; our datastructures work nice with LINQ - you can say, for instance:

    Code (csharp):
    1. if(grid.Values.Any(p => p.IsEnemy))
    2.    GameContinues();
    3. else
    4.    GameEnds();
    and many other useful functions. If there is anything specific you want to know, please let me know :)
     
  31. Middy

    Middy

    Joined:
    Jun 19, 2013
    Posts:
    4
    Thankyou for your answer

    The way I see it I will need.

    - Weighted grid and rangefinding based upon weight, eg how far can I go with X movement points

    - Impassable paths

    - Easy serialization of datastructure

    - High performance framework, must be runnable on a mobile device.

    I am not sure I get the blended landscape?
     
  32. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Say for instance you have a Cell defined as follows:

    Code (csharp):
    1. class Cell
    2. {
    3.     bool IsPassble {get; set;}
    4. }
    and a weigh to calculate travel costs:

    Code (csharp):
    1. float CalcTravelCost(PointyHexPoint start, PointyHexPoint finish)
    2. {
    3.     return ....
    4. }
    If you have a grid of Cells, like this:

    Code (csharp):
    1. PointyHexGrid<Cell> grid = PointyHexGrid.Default(100, 100);
    Then you can call the path finding algorithm like this:

    Code (csharp):
    1. var path = Algorithms.AStar(start, goal,
    2.     CalcTravelCost, //Take costs into account
    3.     cell -> IsPassable //Do not go through impassable cells.
    4. );
    Of course, path finding is not our core focus, so other path finding package offer more flexibility and functionality.

    Weighted range finding is not provided out of the box (but it's a good feature to add; we will definitely do it).

    Depending on how you use weights (for nodes themselves, or for connections between nodes) it should not be hard to add.

    The grid code should not be a performance bottleneck; access is constant time, math operators are fast. The main performance concern would be some of the algorithms, but AStar on even a large grid should be fast-enough for path finding.

    I'll have to play a bit with Serialization to be honest. All our data structures are marked as serializable, but I have not in fact tried it much o.0. I will let you know.

    (The blended landscape example assign one of two states - land or water - to the verts [actually in a separate "vertex" grid, so that data is not duplicated for shared verts], and then selects the right tile based on the states of all it's verts. This way, you can ave blended landscapes. It's more a presentation thing than anything else).
     
  33. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    847
    Is there a way to set up a grid that features normal-sized cells with smaller cells inbetween them acting as very thin walls and blocking access from one normal-sized cell to its normal-sized neighbour? Or am I overthinking things here and there's an easier way to block access from one cell to an adjacent yet walled off other?


    Link's not working. ;)
     
  34. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Well, your way could work, although you would need to write your own map for it. (We use cells as walls in some maze algorithms, but in that case walls and rooms are the same size).

    But perhaps a better way is to use a separate grid, one unit bigger in each direction, where cells are defined as wall corners, like this:

    Code (csharp):
    1. WallCorner
    2. {
    3.   bool IsSouthWall{get; set;}
    4.   bool IsWestWall{get; set;}
    5. }
    6.  
    So you create this grid, and maintain walls in it.

    Code (csharp):
    1. RectGrid<WallCorner> walls = RectGrid<WallCorner>.Rectangle(width + 1, height + 1);
    You will probably want to define methods so you can query the grid with consistent interface:

    Code (csharp):
    1. bool IsWall(RectPoint point, RectPoint direction)
    2. {
    3.    if(direction == RectPoint.South) return walls[point].IsSouthWall;
    4.    if(direction == RectPoint.West) return walls[point].IsWestWall;
    5.    if(direction == RectPoint.North) return walls[point + RectPoint.North].IsSouthWall;
    6.    if(direction == RectPoint.East) return walls[point + RectPoint.East].IsWestWall;
    7. }
    You can use a similar method to update walls:

    Code (csharp):
    1. void SetWall(Rectpoint point, Rectpoint direction, bool isWall)
    2. {
    3.  if(direction == RectPoint.South) walls[point].IsSouthWall = isWall;
    4.    if(direction == RectPoint.West) walls[point].IsWestWall = isWall;
    5.    if(direction == RectPoint.North) walls[point + RectPoint.North].IsSouthWall = isWall;
    6.    if(direction == RectPoint.East) walls[point + RectPoint.East].IsWestWall = isWall;
    7. }
    Does this make sense?

    (There is also a way to use edge grids, but in my experience it is conceptually much more difficult to use. Of course, if you also want to render walls, that approach is better. Let me know if that is the case, then I will explain it).

    Cool, thanks for letting us know. (Jonathan is trying to fix it but there seems to be a forum bug that prevents it... but if you want to check it out, here it is:

    http://gamelogic.co.za/30-games-in-30-days/
     
    Last edited: Nov 5, 2013
  35. Jonathan-Bailey

    Jonathan-Bailey

    Joined:
    Aug 12, 2013
    Posts:
    79
    @c-Row Thanks for the heads up. I have fixed the link :)
     
  36. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    847
    I think I understand where this is going, yes, though I had to scribble it down to make sense of it. Please ignore that the west walls are actually east walls in my picture. :D


    That would be great.
     

    Attached Files:

  37. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Your picture describes exactly what I meant :)

    To use the edge grids, is like I said, a little bit tricky, but not too hectic.

    First thing you need to understand is that the edge grid of a RectGrid is a DiamondGrid.

    $rooms.png

    In this pic, the black is the walls grid, the yellow is the rooms grid.


    To use it, create one from your original grid:

    Code (csharp):
    1. RectGrid<RoomCell> roomsGrid = RectGrid<RoomCell>.Rect(width, height); //original
    2. DiamondGrid<WallCell> wallsGrid = roomsGrid.MakeEdgeGrid<WallCell>();
    Let's assume WallCell looks like this:

    Code (csharp):
    1. class WallCell
    2. {
    3.   bool IsWall {get; set;}
    4. }
    While looking into this, I see there is no function that will give you the edge between to faces o.0... We will include this, for now, we can write one:

    Code (csharp):
    1. bool GetEdgeBetween(RectPoint p1, RectPoint p2)
    2. {
    3.    var edges1 = p1.GetEdges().ToList();
    4.    var commonEdges = p2.GetEgdes().Where(edge => edges1.Contains(edge)); //Find the intersection
    5.  
    6.    if(commonEdges.Count() == 1)
    7.    {
    8.        return commonEdges.First();
    9.    }
    10.    else
    11.    {
    12.        // report error etc.
    13.    }
    14. }
    15.  
    Now with that in place, you can maintain walls between rooms, and query the structure easily, for example:

    Code (csharp):
    1. if(!wallsGrid[GetEdgeBetween(room1, room2)].IsWall) wallkThroughTo(room2);
    WallCells can be rendered the same way as RoomCells using sprites or whatever system you use. If you render walls over rooms, there must be enough transparent so that the room tiles are visible.

    Here is an example of a wall tile:

    $wall.png

    (In reality all the grey will be transparent, I just coloured it differently so it's easier to see what's going on).

    But the tricky bit is figuring out the map.

    (We had a feature requests for automatically making the map already, that should be in the next update).

    For centered cells, you can just use a centered map with the right dimensions.

    For maps aligned differently, you may need to apply a small translation.
     
    Last edited: Nov 5, 2013
  38. Shirken

    Shirken

    Joined:
    Sep 5, 2013
    Posts:
    7
    Hello,

    I recently purchased your Grids package and am fairly new to game development. I was wondering if the source code for the additional games you are building in your 30 games in 30 days challenge will become available at some point? I would love to see more examples of using the grid package in different ways and with a character controller to help me learn and understand it. Thank you!

    Lance
     
  39. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hi Shirken,

    We definitely want to make the source code available in some form. We will also be including some of the additional tech we built into the library proper, once we had a chance to test it properly, including wrapped grids, super grids, and other goodies. :)
     
  40. Shirken

    Shirken

    Joined:
    Sep 5, 2013
    Posts:
    7
    That is great to hear! Maybe i the interim you could offer some advice. I have managed to generate a flat hex grid using the documentation and tutorials. But it has lead me to two questions.

    1. When the grid gets larger, as you go further up its height, and click on tiles, it slowly becomes more and more off. It doesnt seem like going across the width of the grid suffers from the same issue. Here is what I have in my Update()...

    Code (csharp):
    1.  
    2.         if(Input.GetMouseButtonDown(0))
    3.         {          
    4.             Vector3 worldPosition = root.transform.InverseTransformPoint(cam.ScreenToWorldPoint(Input.mousePosition));
    5.             FlatHexPoint hexPoint = map[worldPosition];
    6.            
    7.             if(grid.Contains(hexPoint))
    8.             {
    9.                 if(grid[hexPoint] != null)
    10.                 {
    11.                     grid[hexPoint].gameObject.active = !grid[hexPoint].gameObject.active;
    12.                 }
    13.             }
    14.         }
    2. I tried converting the stress test code to generate a large complex flat hex grid and got that working.I noticed that the stress test grid uses Blocks and the other example code uses Cells. What is he difference? When I convert my grid to use cells it seems to have a very notable slow down.

    Sorry if my questions are incredibly basic or dumb, but I am just starting out and trying to grasp all of these new concepts.

    Thanks Again!

    Lance
     
  41. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hi Lance;

    Your questions are not dumb at all.

    Before I can answer the first; could you please tell me what cell dimensions you use for the map? (There is a subtle bug there and this may be cuasing the issue; it should be fixed in the next update).

    For the second: the reason it is so much slower is because of NGUI. Cells use NGUI sprites, while blocks are normal Unity meshes. I am sure it would be possible to optimise sprites to be as efficient using a pool for example - basically create enough sprites to fill the screen, and then re-use them as needed.

    This may get you started on this route:

    Code (csharp):
    1. List<Cell> cells; //declared in your class and filled with enough cells to fill the screen
    2. PointyHexGrid<CellData> grid;
    3.  
    4. //......
    5.  
    6. //in update
    7.  
    8. int cellIndex = 0;
    9.  
    10. foreach(point in grid.Where(IsOnScreen(point))
    11. {
    12.     var cell = cells[cellIndex];
    13.  
    14.     UpdateCell(cell, grid[point]);
    15.  
    16.     cellIndex++;
    17. }
    You will need to write your IsOnScreen function (you could use the maps for example to test this) and UpdateCell (which just sets up the cell according to the data in grid[point]. Of course, you can also include things to check whether it is necesssary to update cells, and so on.
     
  42. Shirken

    Shirken

    Joined:
    Sep 5, 2013
    Posts:
    7
    Thank you so much for your help!

    For the first question, I am using the following:

    Code (csharp):
    1. private readonly Vector2 HexDimensions = new Vector2(84, 74);
    I noticed that it is off if I use blocks or cells alike. I tried using the NGUI functions and the unity functions, same results. I also tried playing with slightly different cell sizes without any luck. If this is the bug you mentioned, I will look forward to the update!

    As for the second question, I am going to play around with what you described. As an aside, is it possible to create a game map using blocks instead of cells? And is there a drawback to doing so?

    Thanks again for your help. I am really looking forward to learning how to make a game map and controllers running with the Grids framework.
     
    Last edited: Nov 15, 2013
  43. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hmmm no that looks right. Can you also show the code where you build the grid, setup the map, and do any other map operations? I think it might just be a setting somewhere, or perhaps an issue with a parent.

    As for cells or blocks - indeed you can use either. In the stress test example I used blocks because it performed better than the sprites, but in general, for 2D, I'd rather use NGUI sprites. If you want 3D blocks though, the actual mesh objects will do the job.
     
  44. Shirken

    Shirken

    Joined:
    Sep 5, 2013
    Posts:
    7
    Of course, here is the BuildGrid function.

    Code (csharp):
    1.  
    2. public void Start()
    3.     {
    4.         StartCoroutine(BuildGrid());
    5.     }
    6.    
    7.  
    8. public IEnumerator BuildGrid()
    9.     {  
    10.         totalCellCount = 0;
    11.         grid = FlatHexGrid<Cell>.FatRectangle(width, height);
    12.        
    13.         map = new FlatHexMap(HexDimensions)
    14.             .To3DXY();
    15.        
    16.         int cellCount = 0;
    17.        
    18.         foreach(var point in grid)
    19.         {
    20.             Cell cell = Instantiate(cellPrefab);
    21.             Vector3 worldPoint = map[point];
    22.            
    23.             cell.transform.parent = root.transform;
    24.             cell.transform.localScale = Vector3.one;
    25.             cell.transform.localPosition = worldPoint; 
    26.            
    27.             cell.SetColor(ExampleUtils.colors[point.GetColor3_7()]);
    28.             //cell.SetText(point.ToString());
    29.            
    30.             grid[point] = cell;
    31.            
    32.             cellCount++;
    33.             totalCellCount++;
    34.            
    35.             if(cellCount >= cellsPerIteration)
    36.             {
    37.                 cellCount = 0;
    38.                 yield return null;
    39.             }
    40.         }
    41.     }
    42.  
    The only other code I have so far in my update is to move the camera around. It allows for arrow keys to move up,down,left right. Then I also have some code to allow zooming in and out with the orthographic camera. But the issue occurs regardless if I have zoomed in or out at all with the camera. That code is below.

    Code (csharp):
    1.  
    2.         //------------------Code for Zooming Out------------
    3.         if (Input.GetAxis("Mouse ScrollWheel") < 0)
    4.         {
    5.             if (cam.fieldOfView<=100) {
    6.                 cam.fieldOfView +=2;
    7.             }
    8.             if (cam.orthographicSize<=1) {
    9.                 cam.orthographicSize +=0.05f;
    10.             }
    11.         }
    12.        
    13.         //----------------Code for Zooming In-----------------------
    14.         if (Input.GetAxis("Mouse ScrollWheel") > 0) {
    15.             if (cam.fieldOfView>2) {
    16.                 cam.fieldOfView -=2;
    17.             }
    18.             if (cam.orthographicSize>=.01f) {
    19.                 cam.orthographicSize -=0.05f;
    20.             }
    21.         }
    22.  
    Thank you!

    Lance
     
  45. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hi Lance,

    As far as can see, your code looks good, but maybe if I can play with what you have I can find the issue. If you want to, please send me an email with the package showing the problem (herman at gamelogic dot co dot za).
     
  46. Shirken

    Shirken

    Joined:
    Sep 5, 2013
    Posts:
    7
    Last edited: Nov 18, 2013
  47. Herman-Tulleken

    Herman-Tulleken

    Joined:
    Nov 20, 2009
    Posts:
    358
    Hi Lance,

    I just tested your package with Grids 1.4 and Grids 1.5. It works with 1.5, but not 1.4, so it looks like it is that bug after all. We are submitting the updated today, but I can email the newest package to you; just let me know.

    Herman
     
  48. Shirken

    Shirken

    Joined:
    Sep 5, 2013
    Posts:
    7
    Herman,

    I can wait. It wont affect what I am doing since I am just experimenting as of now. Thank you for looking into that for me!

    Lance
     
  49. Jonathan-Bailey

    Jonathan-Bailey

    Joined:
    Aug 12, 2013
    Posts:
    79
    Rect Grids Now Available in the Asset Store

    We have created another subset of the Grids library, this time specific to rectangular and diamond grids.

    Rect Grids is a subset of our Grids package and has been released on the Unity Asset Store for $40. It supports the full Grids library features, but is restricted to rectangular and diamond grids. Check out some examples of games we have made with rectangular and diamond grids in our 30 games in 30 days project.

    It is also possible to upgrade to the full Grids package for $60 after purchasing Rect Grids. Email us for details and to arrange an upgrade.

    Asset Store Link
    https://www.assetstore.unity3d.com/#/content/13000


    $RectGrids_680x340.png
     
  50. The Bag

    The Bag

    Joined:
    May 28, 2012
    Posts:
    24
    Has anyone got this running on iOS? The shape creation methods aren't working with AOT:

    Code (csharp):
    1. ExecutionEngineException: Attempting to JIT compile method 'Gamelogic.Grids.AbstractShapeInfo`5<Gamelogic.Grids.PointyHexShapeInfo`1<Cell>, Gamelogic.Grids.PointyHexGrid`1<Cell>, Gamelogic.Grids.PointyHexPoint, Gamelogic.Grids.PointyHexPoint, Gamelogic.Grids.PointyHexOp`1<Cell>>:.ctor (Gamelogic.Grids.ShapeStorageInfo`1<Gamelogic.Grids.PointyHexPoint>)' while running with --aot-only.
    2.  
    3.   at Gamelogic.Grids.PointyHexShapeInfo`1[Cell]..ctor (Gamelogic.Grids.ShapeStorageInfo`1 info) [0x00000] in <filename unknown>:0
    4.   at Gamelogic.Grids.PointyHexOp`1[Cell].Rectangle (Int32 width, Int32 height) [0x00000] in <filename unknown>:0
    5.   at Gamelogic.Grids.PointyHexGrid`1[Cell].Rectangle (Int32 width, Int32 height) [0x00000] in <filename unknown>:0
    6.   at PointyHexTest.BuildGrid () [0x00000] in <filename unknown>:0
    7.   at PointyHexTest.Start () [0x00000] in <filename unknown>:0