Search Unity

Grid Framework [scripting and editor plugins]

Discussion in 'Assets and Asset Store' started by hiphish, Jul 24, 2012.

  1. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    Hi

    You don't need to specify a material, if there is none a default material will be generated at runtime instead. Just set the axis colours to whatever colour you want and that's it. The Render Material field is just there if you don't like my default shader and want to write your own shader. The materials I included with the examples were meant for blocks, not grids, that's why you see only a black grid but a red sphere. (Technically the grid is dark red and if you wiggle around your directional light you can find an angle where it is properly illuminated)

    I'm afraid that's not possible. What you are looking for is a grid-shaped mesh that's put on top of the terrain like if you put a fishnet over am uneven surface in real life. Grid Framework is mainly a framework to do grid-based math for you with additional features like rendering and snapping added because it made sense, but it doesn't generate meshes. It would be possible to use a grid's information for generating meshes, that's what Vectrosity does after all, but I haven't looked into this possibility yet. One more thing to put on my list.
     
  2. Udorn

    Udorn

    Joined:
    Feb 9, 2013
    Posts:
    10
    Okay thanks, then it seems I have to use a second grid, because I want to use a nearly invisible colour, which wouldn't be useful in the editor. Perhaps a feature for the future, to be able to choose colours for the editor and the game separately? Or do you know any standard shader, which would show the correct colour? I've tested some of them, but didn't see the wanted result.
     
  3. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    Rendering works only at runtime, while in the editor the grid is drawn using gizmos, so shader have no effect in the editor. Separate colours for rendering is a good idea as long as I make it optional, I'll add it with the next update, should easy enough. Until then you can ue a simple script, no need for an extra grid:
    Code (csharp):
    1.  
    2. void Awake(){
    3.     GetComponent<GFGrid>().axisColors = new GFColorVector3( xColor, yColor, zColor);
    4. }
    5.  
    This code changes the three colours of your grid once the game starts. See the included scripting reference for information on the GFColorVector3 class, it's similar to unity's Vector3, except with colours instead of floats numbers.
     
  4. rlevere

    rlevere

    Joined:
    Feb 13, 2013
    Posts:
    5
    Hello,

    I have purchased your Grid Framework and was hoping you could help me out with something. I have the following GFRectGrid, but it is not rendering as expected based on the parameters I have given it. The 'Custom Rendering Range', in particular, doesn't behave as I would expect.

    For the range, I have set 'From' to 0,0,0 and 'To' to 25,0,26, but the visible grid is actually 20,0,19, with an addition part of the grid cell lines being drawn long the x axis, for some reason. Can you tell me what I'm doing wrong here?

    Thank you.

     
  5. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    The size and rendering range are measured in world unit length, not grid unit length. I did it so those two could work independently, what you want to do is multiply your desired length times the spacing for each axis. You have a spacing of (1.3, 0.1, 1.3), so if you want your grid to span 25 x 26 squares you need a renderTo of 1.3 x (25, 0, 26) = (32.5, 0, 33.8). I can see how this might be confusing, I'll try to add an option for relative size to Grid Framework, thanks for the idea.
     
  6. rlevere

    rlevere

    Joined:
    Feb 13, 2013
    Posts:
    5
    That's exactly what I need to know. I figured I was misinterpreting a value somewhere.

    Thanks for the quick reply.
     
  7. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    This update brings you two new features, both were suggested by customers. The first one is the ability to set a separate set of colours for rendering instead of using the same colours as for drawing. Let's say you want a barely visible grid in the game but a clearly visible grid in the editor. Until now you either had had to have two grids or use a script to change the colours once the game starts. Both options worked fine but required more work than needed, now you can do it out of the box. Of course it is entirely optional, so if you don't set anything you will be using the same colours for rendering and drawing.
    The other new feature is relative size. Usually the size and the renderFrom/renderTo vectors were interpreted as absolute world unit lengths. I did this intentionally so the grid's size would be independent from its spacing (or radius and depth for hex grids). Of course not everyone is concerned about that sort of thing, some people would simply like to say "make my grid this many blocks tall" instead of having to multiply the desired size with the spacing. Turning on relative size now does exactly that for you. Here is a visual example where the values are interpreted as absolute (left) and relative (right) length:
     
  8. Udorn

    Udorn

    Joined:
    Feb 9, 2013
    Posts:
    10
    Hi,

    is it intended, that the Grid Align Panel looses the grid object each time the Play button has been pressed? Or is it some strange issue with my local setup?

    BTW thanks for the new color options, that was fast implemented. :)
     
  9. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    Shouldn't happen. Here is what I did: drop a grid into the panel, press play and then press play again. Try only that and tell me if it still resets. What will happen though is that the field resets when the scene changes because grids only exist inside the scene where they were created. As long as you don't change the scene though the flied should not reset.
     
  10. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    Rendering a grid at runtime causes massive constant garbage collection. I'm taking a 90% performance hit while it's running (is it forcing vsync on?). Please see the below profiled.


    LINK TO IMAGE

    Any idea how to improve this? I from 900 FPS average to 100 FPS when grid is set to render.
     
  11. Udorn

    Udorn

    Joined:
    Feb 9, 2013
    Posts:
    10
    I just tried it and it happens for me only, if I've selected "Maximize on Play". If Maximize is not checked and I press play, then the grid doesn't get lost.

    I don't know, if it relates to the problem, but my project is always shown as modified, even if I press Strg-S.
     
  12. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    That is weird. How large is your grid? I need to make something really absurdly large (like a 100 x 50 x 2 grid) to get a 40 FPS dropdown. Are you using a custom shader? How many cameras are in your scene?

    The part I don't understand is why the garbage collector is being called. Usually this means something is being instantiated and destroyed all the time. The only possible bottlneck I see is the calculation of lines. Basically we need for each line a starting point and an end point, so the larger your grid is, the more points we need to calculate at a time. I considered the loss in performance to be negligable, so I didn't prioritize caching values but if it makes the garbage collector go crazy I'd need to find a way for the program to re-use old points if the grid hasn't changed.

    Could you please first answer my other questions and try using an alternative shader? Owlchemy Labs have a collection of iOS optimized shaders, if things are still bad then we know it's not my shader.
    http://owlchemylabs.com/content/
     
  13. SimtropBuggi

    SimtropBuggi

    Joined:
    Feb 15, 2013
    Posts:
    98
    I'm working on a CityBuilder game and there are quite a few systems that will be calculated on a grid system. An example of this is pollution. This will allow me to limit the amount of calculations to make the game respond to changing elements. I will need to do a per-grid-box calculation.

    Is it possible to have a different grid for each unity terrain? That way I can limit which grids are updated based on how large the city is. If a city only exists on one terrain I only need to calculate on the grid on that terrain.

    I need the included feature to translate grid coord's to worldspace in order to update things like landvalue. So my desirability grid will influence landvalue grid, for example. Then when a building grows in the city I can look-up the values I need based on the buildings world space and how it relates to the grid location. I will be using the building 'origin' as the lookup position to get the exact grid location.

    A brief list of the simulations that will be grid-based are
    Pollution (air, water, light, and noise, et al)
    Desirability
    Tourism Rating
    Resources (iron, coal, soil fertility, etc)
    Crime
    City Border

    These are the big ones. I will obviously need some optimizations to limit the amount of grid locations the game processes, but that is on me to work out.

    The only part I will need to render is when the player enables data-overlays I will need to render the specific grid values as a sort of heat-map. Would it be possible to project the colors onto the terrain?
     
  14. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    It's 100 x 1 x 100 grid. There are 2 Cameras (Main and NGUI), but only 1 is set to see the grid layer (main camera).

    I was thinking the same thing, but I'm not destroying anything that I am aware of. The grid is created at run time and its render bool is flipped off or on based off a key. I then have 2 other grids (1 green, 1 red) that are 1 x 1 x 1 that I simply move around for the grid highlighting (they're just moved, never destroyed).

    Have tried multiple shaders: default, diffuse, mobile diffuse, etc.. they all have the same behavior. The grid is created at runetime based off my Rotorz grid size so it's a 1 to 1 perfect match. That all works fine and it displays fine in Editor. Soon as "Render Grid" is flipped by the toggle key and it displays in game play the GC goes nuts as seen in my screenshot.

    Below is a screenshot of my grid settings created at runtime (render is off, but when it's on is when the GC goes nuts).

     
    Last edited: Mar 12, 2013
  15. artonator

    artonator

    Joined:
    Sep 12, 2009
    Posts:
    69
    Is there a way I can snap object( or vertex) to a grids in editor mode?
     
  16. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    Ok, instead of 100 x 1 x 100 grid I set it to 100 x 0 x 100 and all the performance problems are gone. So seams to be something with the grid having depth or something. As my game is 2.5D I only need a flat grid so this will work out fine anyway.
     
  17. TumbaBit

    TumbaBit

    Joined:
    Feb 17, 2013
    Posts:
    9
    I really wish you could work with someone who could rewrite this in javascript.
     
  18. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    I don't. It should remain C#. Why do you want it as UnityScript (not JavaScript)?
     
  19. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    I'm currently working on an optimization effort that should limit the use of the Garbage Collector. The idea is that we can reuse the same line points if the grid hasn't changed instead of calculating the same thing every frame. If you are wondering why I didn't do this from the start, it hasn't been possible to do it in a reasonable way until recently when I figured out how to use properties properly with Unity. An update should come soon. Obviously it won't do anything for grid which are being changed, but that's to be expected.

    OK, I think I understand what you mean, please tell me if I misunderstood you. You want to have a city (like in SimCity?) that's built out of square parts. You will have several grids for different purposes on top of each other that represent different statistics.

    Sure, you could have several grids, but it would be a waste of effort and time; a grid is nothing but a mathematical separation of space. If all grids are to have the same values (size and the likes) it would be better to use just one grid for reference and have various classes access that one grid. Here is how I would do it: I'd have one static MainManager class that references the grid and communicates with the other manager classes.
    Code (csharp):
    1.  
    2. public static class MainManager{
    3.     public static GFGrid cityGrid; // this should be read-only just in case
    4.     public static void RegisterGrid(GFGrid grid){
    5.         cityGrid = grid;
    6.     }
    7. }
    8.  
    The GameObject that has the grid attached (grids are components) will register the grid when the game starts
    Code (csharp):
    1.  
    2. public class GridReporter: MonoBehaviour{
    3.     public void Awake(){
    4.         MainManager.RegisterGrid(GetComponent<GFGrid>());
    5.     }
    6. }
    7.  
    Now another manager class, let's say PollutionManager, can access the grid from MainManager and use it for example to build a matrix where it will store for each square the pollution:
    Code (csharp):
    1.  
    2. public static class PollutionManager{
    3.     // pollution would be your own data type, like a float or whatever
    4.     public pollution[,] pollutionMatrix;
    5.  
    6.     public void BuildPollutionMatrix(){
    7.         // use MainManager.cityGrid to calculate the size of the matrix
    8.     }
    9. }
    10.  
    Of course this is just an idea, I wanted to minimize the amount of grids used in the game. The advantage is that you only need one grid, any calculations that can be performed in one manager class can be performed in another, in fact I'd move as much as possible into MainManager. Keep in mind that a grid does not store any game data, it is just there to do the math. In some of my examples I use a manager class together with a grid to build a matrix and use that for the actual gameplay. For instance in the sliding puzzle example I completely threw Unity's physics out of the window and replaced it with something simpler that feels much more appropriate for such a game (no offense to PhysX, but it was clearly meant for 3D action games, not for blocks touching each other constantly).

    Of course if I misunderstood you please correct me so I can help you properly.

    As i said I'm working on optimization. The difference between a 100 x 1 x 100 and a 100 x 0 x 100 grid may not seem like much to the eye, but in the latter case you are preventing 20,806 points form being calculated every frame (101 * 2 = 202 lines for the second layer and 101 x 101 = 10,210 lines for the lines connecting the two layers and finally all that times two because we need both a starting and an ending point for each line)! As i said, I'm working on an optimization to recycle old lines instead of just throwing them away, so hopefully things will get better.

    I'm afraid that is technically impossible. The proper name of the language is UnityScript, it just looks like JavaScript and it's called JavaScript because it sounds better, but in essence it's just a scripting language to manipulate the standard Unity API. I don't want to start a language war here and if all you want to do is manipulate the standard Unity API then UnityScript is good enough, but for anything beyond that you are better off with C#.

    If you want to do more, like write a library and have it properly integrate with the editor or introduce your own types then UnityScript won't do it, it simply lacks features that C# has. The fact that you have a proper .NET (or Mono) development environment to your disposal is what makes Unity really shine. You could even write your own physics and use that instead of PhysX (which I did for the sliding puzzle example!). I used to work with UnityScript, my first prototype of Grid Framework was written in UnityScript, but I quickly realized that if I wanted to be serious about it and wanted to create something worth paying money for, that C# was the only way to go.

    Aside from language features I would in fact encourage everyone to ditch UnityScript entirely in favour of C#, you can use the proper .NET and Mono documentation, there is much more information available online, the language is more verbose instead of hiding things behind "magic" and if you find yourself in a spot where you need "more" you can just make "more".

    All that said, this is just my opinion, so if you want to stick with UnityScript that's your choice. Grid Framework works perfectly fine with UnityScript and the only things you will be missing is what you will be missing anyway simply because of language limitations.
     
  20. SimtropBuggi

    SimtropBuggi

    Joined:
    Feb 15, 2013
    Posts:
    98
    Thanks for the excellent response. Yes that is the way I want to do it.

    Since the grid is a component, I'm assuming one grid can be used for each terrain? That way if I have 10x10 terrains I can only focus on the terrains the city occupies and only calculate using those grids.
     
  21. Krileon

    Krileon

    Joined:
    Oct 30, 2012
    Posts:
    642
    Awesome, looking forward to next release. Keep up the great work! One of the best assets I've purchased for sure.
     
  22. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    Um, what exactly do you mean by "terrain"? Do you mean Unity's own terrain component? Or your own data type that represents one square of city surface? I'm having a hard time following what you mean and how you want your game to work, could you please elaborate with a simple sketch? You can PM me if you don't want to do it in public.
     
  23. r-gamer

    r-gamer

    Joined:
    Mar 22, 2013
    Posts:
    6
    Hello hiphish

    We are trying to build a city simulation game like cityville, but unfortunately we are new to unity3d and we dont know how to start, we found your framework useful for our game and we already purchased it, but still we are unable to start, can you help us with whatever resources such as tutorials for this type of games or templates?

    Thanks in advance
     
  24. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    I don't know about city building specifically, but here are a few links that helped me get familiar with Unity. Also, since you are just starting out, don't learn UnityScript, go for C# straight; I know most examples are written in UnityScript and the verbosity can be intimidating, but you will have much more control over your game and you will be able to extend it beyond what Unity offers, not to mention how much more information there is for C# on the internet. UnityScript is good enough if all you want to do is manipulate the standard Unity API, which is enough for a 3D action game, but the more you deviate from the norm, the more painful the limitations of UnityScript will be.

    http://www.youtube.com/watch?v=gvcbPHr99Jg (making sense of Unity - the first tutorial I watched, it's a little outdated, but not by much. He uses UnityScript, but the Unity API is the same for both languages)
    http://www.unity3dstudent.com (Will Goldstone also wrote a book about Unity, I haven't read it, but aparrently people liked it)
    http://www.youtube.com/watch?v=N2zdwKIsXJs (the first in a series of C# tutorials, these guys got me to switch away from UnityScript)

    Of course there is also the rest of the Unity Community and the Wiki, but I would go over those links first, especially the first two, just to get familiar with Unity.
     
  25. r-gamer

    r-gamer

    Joined:
    Mar 22, 2013
    Posts:
    6
    My concern is about the type of graphic that i have to use is it 3d or 2d in term of performance of the game on mobile and web, since the game will have many buildings and objects, do you have any idea about this, also is there any showcase for city building games using grid framework.

    and thanks for the tutorials.
     
  26. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    It depends. From the looks of it Cityville is using isometric 2D graphics. Isometric graphics are a topic on their own; what you are doing is making 2D graphics look 3D. The main challenges are that 2D graphics systems are axis-aligned with the screen while isometric tiles are not. You also have to sort the depth, objects in front should cover objects in the back, but since you are in 2D there is no such thing as "back" or "front", so you need to organize the drawing order through code. It's not impossible, but Unity is a 3D engine, it gives you great tools to work with 3D worlds; using 3D to display 2D that looks like 3D is just making things more complicated than they would need to be. In that case you'd be better off making your own engine from scratch (or using one that was designed for isometric 2D). Here is a tutorial I found recently, it's for XNA but you can translate it to whatever you would want to use instead:
    http://xnaresources.com/default.asp?page=TUTORIALS

    Now, if you want to use 3D graphics things get much simpler. You can scratch all the isometric trickery, there is no need to fake 3D when you are using actual 3D. In that case your graphics need to be created in a 3D modelling application. There are many professional ones, but their prices are "professional" as well, if you cannot afford them just use Blender, it's free, runs on anything and good enogh for simple models:
    http://www.blender.org

    When it comes to performance it depends on how detailed your models are. Since you are going for simple block-like objects you can create good looking results with very simple meshes, so it shouldn't be much of a problem for mobile devices or browsers. Of course you'll need to test and optimize on your own, but if mobile phones these days can play something like Infinity Blade, then a few blocks shouldn't be a problem. Also make use of tricks like normal mapping to create the illusion of details instead of actually modeling those details. I don't know much about modeling, so you should ask other people.
     
  27. r-gamer

    r-gamer

    Joined:
    Mar 22, 2013
    Posts:
    6
    thank you for your great support, we will do many performance tests on many devices with different 3d models on both mobile and web, then we will take informed decision about it.

    i think your framework is great for such games and i hope you include showcases and more features for city building genre , also since there is no assets available in the asset store for such game its a good deal to start implementing the framework for such purpose.

    Thanks again
     
  28. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    Well, there is the grid snapping example that's provided with Grid Framework, that shows how you can place blocks (like buildings) onto the grid and have them auto-snap at runtime. I don't want to make more such examples, simple because this is Grid Framework, not city-building-game framework, such examples would just bloat the product, they would confuse other users and they would be a clear violation of my design priciple of providing a general purpose framework. I don't make them publicly available, but I have a strict set of design principles for what Grid Framework does and what it doesn not, and I have to stick to these rules in order to maintain the focus of my project. If I were to just include anything that comes to my mind I would end up with a bloated monstrosity of code. Of course these rules are not set in stone, but if I ever wanted to change or override them I woul need a very good reason to do so. (of course I do take suggestions into consideration and a number of features made their way into the pruduct based on customer suggestions, but I always need to think twice about everything)
     
  29. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    Version 1.2.4 has been approved by the Asset Store team. Here are the new features:

    • a caching feature that keeps the activity of the grabage collector low now, instead of re-calculating the end points of lines every frame we can re-use them instead as long as the grid hasn't been modified.
    • a new example shows you how to create seemingly endless grids without the overhead of actually having a gigantic grid
    • explanations about rendering performance in the user manual

    Please enjoy the new performance improvement and thank you for your support.

    P.S.: Here is the video for the new example:
     
  30. Trithilon

    Trithilon

    Joined:
    Aug 2, 2012
    Posts:
    30
    Brilliant release!
    Looking forward to Pathfinding :D
     
  31. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    Pathfinding will still be quite a while, I still need to learn more about the topic and, more importantly, I still need to figure out a way that's neither too hard to hook up to your project (or else what's the point?), nor too restrictive (which would dictate how you have to design your game, where it becomes a kit instead of a framework)
     
  32. NandusMasta

    NandusMasta

    Joined:
    Apr 9, 2011
    Posts:
    63
    I just wanted to say that this seems a great asset and I am probably going to be getting it soon. Regardless adding pathfinding to it, would really make it shine; as most devs will want to move stuff in the grid. It's the only thing really missing IMO, all other things are more details than anything else. Another alternative is to get Simplepath and try to integrate it's Path Manager class with your grids, instead of using the default ones in the package.
     
  33. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    I agree, but there is still quite a few questions I need to answer first. How will the user define way cost? What will the pathfinding return? A list of Vector3? How will the user hook up his or her game logic to the framework? How will the graph react to changes in the scene? I need a pathfinding solution that can work for both a freeroaming space game with asteroids flying around in real time and a turn-based strategy game where different unitys have different travel costs over the same terrain.
     
  34. NandusMasta

    NandusMasta

    Joined:
    Apr 9, 2011
    Posts:
    63
    For movement cost, I would suggest a simple float value, To find out how far a unit can go in a turn, I think you only need to loop the resulting path and get the tiles up until the unit runs out of movement points. For RTS like games, you don't have this problem, but for TBS games it's practically a requirement. You can assign a infinite value if you don't want any unit ever crossing the tile. There should also be user defined type of tiles, so we can have units moving only on water, air, etc.

    Regarding the pathfinding itself, in my opinion it should return at least a list of tiles, as previously mentioned. Nevertheless it would also be great, to have the path manager provide a method(same one overloaded probably), to return the Vector3 positions of the actual center points of each title as well. So the main method for the Path Manager should receive the origin and destination, plus which tipes of tiles the unit can traverse. I think that should be enough.

    Changes in the scene should be propagated to the grid, for example if a bridge is built, the tiles involved should change to land and have a finite movement cost accordingly. Hooking up the gamelogic to the framework should be no different that other pathfinding solutions, you get a path request, you process it according to these variables and give a result. Moving the units and reflecting changes to the grid, should be up to the dev using the framework, so that's covered.

    Sorry if this is mostly rubbish, I am just thinking and typing as I go. This probably is not near good enough, but it's always nice to shared thoughts on this, so that we may all understand the problems before us better. Hopefully it will be useful to somebody else as well. In any case, sorry for the long post :)
     
    Last edited: Apr 18, 2013
  35. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    Don't apologize, I like getting input and suggestions, even if it's rubbish at least the idea was brought up and considered.

    Here is how I see it: what a user expects from pathfinding is a path. What is a path? In graph theory terms it's a list of edges (e_1, e_2, ..., e_n) where for each pair of edges e_i and e_(i+1) they share one vertex. Thus it would be sufficient to express our path as a list of vertices (v_0, v_1, ..., v_n). Since the vertices of the graph represent positions in Unity's world the result would be a list of Vector3 values, our waypoints.

    Now that we know what we want the next question is how do we get it? First of all we need a graph, we can build one from a grid, just set the desired from and to values and let Grid Framework do the magic. The "boxes" of the grid will form our vertices and each vertex will be connected through an edge to all adjacent vertices with a default weight (travel cost) of 1 (float value).

    This isn't enough though, we still need to assign the proper weight to all the edges (impassable edges will have infinity as their cost). I will leave this part to the user, because it's too specific for each game type. It has to be possible to adjust individual edges without affecting the rest of the graph, or else even something simple as building a bridge would cause step 1 to run again.

    Now that we have our graph we can start searching for paths. A seeker object says which graph it wants to use (we should have different graphs for different types of units, like flying units, land units or ship units) and where it wants to go to, then the framework translates the seeker's position and the target destination into vertices, calculates the path and returns the list back to the seeker. The user can then use these waypoints for whatever he or she wants, like pass them to iTween to create a smooth Bézier curve to walk along or whatever. Once the list has been returned Grid Framework's job is done (at least as far as pathfinding is concerned).

    That's the theoretical part, but what would it look like in an actual game? Let's take something simple like a turn-based tactical game with tiles. We have three types of units: infantry units can traverse any ground except walls, but at different speed. Mobile units are similar, except they can't traverse water and they are faster on open ground but slower in forests. Flying units can taverse any tiles. Ship units can traverse water very quickly, but not land.
    This means we need to build four different graphs once the game starts. Then, each tile (which is a GameObject placed by the user in the editor) tells each graph how expensive it is. This raises the question of what graph structure to use; obviously the cost for going from road to forest is higher than from forest to road. I think I need a directed graph and two edges between each vertex, one for each direction, i.e. instead of v_1 -- v_2 I'd have v_1 -> v_2 and v_1 <- v_2.
    Now that everything is in place the game can start. The player clicks a tank and then clicks on the tank's target destination. The tank picks its "mobile units" grid, calculates the path, drives along it and once it's there it marks that tile as occupied (infinite travel cost) in each graph and restores the travel cost of its original tile back to its natural value. This part would be up to the user to implement, but Grid Framework would offer a nice function to translate grid coordinates to graph vertices.
    This would also allow the playing field to be dynamic. You could for example build bridges, trigger traps or flood areas and have the grids adapt to the changes.

    Now for a real-time example, a 3D space game with moving obstacles like ships or asteroids. The idea is the same, except here we would need to update the graphs in regular intervals. The real complexity would come from how large a 3D graph can become, a grid would not be a very good choice. It would make more sense to use actual geometry to construct a 3D nav mesh, but this is clearly outside the scope of my project. The same applies to complex level architecture like slopes and uneven terrain. There are other specialized solutions already out there that do it better.

    There is also the choice of which algorithm to use. A* is the most famous one, but it is not always the best. I had a chat with one of my professors recently, there are faster algorithms, but they all require preprocessing and additional memory space. In the end we concluded that A* was still the best one for this type of pathfinding, those other algorithms were developed for much more complex graphs (like street maps) and computers with more memory and preprocessing times than a game.
     
  36. NandusMasta

    NandusMasta

    Joined:
    Apr 9, 2011
    Posts:
    63
    From a gameplay perspective, any dev will want to have units that have different domains of movement (sea, air, land, space, etc) and have different movement costs according to terrain. For example infantry units might slow down when entering forests, but not as much as armor units. Then each node in the graph should have a domain and a terrain, then the Pathfinder should receive(besides the origin and destination) a list of available domains to the unit(hovertank = land and sea, spaceship = land, sea and space) and how much it costs for the unit to traverse each type of terrain.

    The things is that if each unit will have a different movement cost, across the same terrain, then this needs to be specified by unit and not in a general way. Although you could specify it generally first and then have a modifier for each unit, something like alpine units traversing snow tiles at half the regular cost. I think it's better if it's specified only in the case in which the unit has a different movement cost across the tile than standard. Taking all this into account, a simple sea ship would then get it's path with something like this:

    Code (csharp):
    1.  
    2.  
    3. // This class holds the info for movement cost across domains and into different terrains.
    4. // It should have enumerator or encapsulating classes for the strings
    5. public class TerrainMovementCost{
    6.       public string terrainTag;
    7.       public float cost;
    8.       string domainTag;
    9.  
    10.       public TerrainMovementCost(string domainTag, string terrainTag, float cost){
    11.              this.domainTag = domainTag;
    12.              this.terrainTag = terrainTag;
    13.              this.cost = cost;
    14.       }
    15. }
    16.  
    17. //Origin grid position
    18. Vector2 origin = new Vector2(1,1);
    19.  
    20. //Destination grid position
    21. Vector2 destination = new Vector2(3,3);
    22.  
    23. //Which domains the unit can traverse. A class for this would be better.
    24. string[] unitDomainTag = {water};
    25.  
    26. //Specifies the movement costs for the unit across all available(from the available domains) terrains
    27. //If the movement cost is standard, then nothing should be specified
    28. TerrainMovementCost[] terrainCosts = {new TerrainMovementCost("water", "ocean", 3f),
    29. new TerrainMovementCost("water", "coast", 1f), new TerrainMovementCost("water", "sea", 2f)};
    30.  
    31. // The pathfinder will get the path, in this case in grid positions, with the list encapsulated in the GridPath class
    32. // It should have already be instantiated with the info on all tiles, including default movement cost across terrains
    33. GridPath path = pathfinder.getShortestGridPath(origin, destination, unitDomainTag, terrainCosts);
    34.  
    The pathfinder should check all the paths from the origin to the destination, only those across water tiles in this case, and then get the shortest one; according to the terrains in the grid and the specified cost by the user. Since a unit can traverse several domains, having a grid for each of them, will surely complicate things. I think it might be easier having only one, but I don't exactly know how.

    Sorry for the crappy code and rambling ideas, I am not exactly in the best place or during the best moment for this kind of stuff. But I wanted to contribute something to this, since it's very interesting and will no doubt eventually help me in my project.
     
  37. Danz0r77

    Danz0r77

    Joined:
    Mar 19, 2013
    Posts:
    20
    Hi HiPhish,

    This is a great plugin. I'm just struggling with a Hex grid a little and not sure what I'm doing wrong. Hopefully you can help. I'm clicking on an object that is aligned with the grid, and getting it's coordinates (for now it's just at the center 0,0,0). Then what I want to do is get all the hexes that are 1 unit away, or 2 units away and so on.. I seem to be having a problem though converting worldtogrid and back again - its selecting strange hexes for me.

    Here's the code I'm using:

    Code (csharp):
    1.  
    2. var gridPosition = grid.WorldToGrid(selectedHexClone.transform.position);
    3.                 Debug.Log(gridPosition); // this gives correct value (0,0,0)
    4.                 for (var i : int = 0; i <= grid.size.x; i++) {
    5.                     for (var j : int = 0; j <= grid.size.z; j++) {
    6.                         if (i <= range  j <= range) {
    7.                             newPosition = Vector3(gridPosition.x - i,0,gridPosition.z - j);                
    8.                             Debug.Log(newPosition); //this gives correct grid coordinates
    9.                             newPosition = grid.GridToWorld(newPosition); // this is where it goes wrong
    10.                             Debug.Log("after : " + newPosition);
    11.                             selectedHexClone = Instantiate(selectedHex,newPosition,selectedHex.transform.rotation);
    12.                             newPosition = grid.GridToWorld(Vector3(gridPosition.x + i,0,gridPosition.z + j));
    13.                             selectedHexClone = Instantiate(selectedHex,newPosition,selectedHex.transform.rotation);
    14.                         }
    15.                     }
    16.                 }
    17.  
    Should this work?

    Thanks for your help.
     
  38. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    I don't see anything wrong with your code, could you please explain what you want and what you are getting instead? Preferably wth a screenshot. Also, make sure you read the explanation about the coordinate system for hex grids in the user manual (page 8). There is no real "next" in hex grids, since each hex is connected to six adjacent hexes, so I'm using a herringbone pattern as a shifted cartesian coordinate system. I'll try to explain what your code does:

    - You start at (0,0,0), that's the centre of the central hex.
    - During the next step you go one unit left and one unit front (in Unity the Z-axis goes away from you deeper into the screen), wich means you get the north-western hex from the centre (-1,0,-1)
    - You also go one unit to the right and one unit back (1,0,1), so that means the north-eastern hex.
    - During the second iteration you get the south-western and the south-eastern hex (in releation to the previous hexes) due to how the coordinate system works.

    It's possible you didn't understand the cordinate system properly or my code has actual errors. Please let me know which is the case, if there is an error in my code I need to fix it.

    We have similar ideas, but I am putting the complexity inside the unit, while your solution looks like it is putting the complexity inside the pathfinding itself. This is a case of KISS (keep it simple, stupid), if I bloat my pathfinding then the result will be convoluted and slow. I need pathfinding to be fast and elegant instead. The graph can be prepresented as a 2-dimensional adjacency matrix of float values for example, that's much better than a conglomerate of classes for each node. It might not make much of a difference for a turn-based game where only one unit will be pathfinding at a time, but if I want to have seveal units pathfinding simultaneously I need it to be simple. To accommodate for different needs for different units the user will have to instantiate different graphs (boat graph, infantry graph, flying graph, mobile graph) and have each unit pick its type. You could even do something crazy like turn a tank into a boat and just change which grid it uses. In addition, your solution is complicated even for simple games, while my solution is only complicated for complicated games. Thank you for sharing your ideas though, I always appreciate input :)
     
  39. Danz0r77

    Danz0r77

    Joined:
    Mar 19, 2013
    Posts:
    20
    Hi,

    I think I understand the coordinates system but I've attached a screenshot, with some debug output, so you can get a better idea of what's happening. The grid isn't being rendered in this shot but you can see where the hex object is supposed to appear and where it's actually appearing.



    I'm sure this is something simple I've got wrong probably but see what you think.

    Thanks
     

    Attached Files:

    Last edited: Apr 21, 2013
  40. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    I see, so you want to draw a "circle" around an arbitrary central hex. Since you are using flat sides the shifting is rotated 90° clockwise, this means every second row (not column) is shifted to the right (I should have mentioned this in the user manual as well, I'll correct this with the next update). Here is a drawing (I've omitted the Y-coordinate since it's not relevant here):

    First of all everything depends on whether your central hex has an odd or even Z-coordinate. For the sake of simplicty we will focus on the even case first. In our first iteration we need one unit to the left (-1,0,0) and one unit to the right (1,0,0). During the second iteration we go one unit up and one unit left (-1,0,1) and just one unit up (0,0,1) During the same iteration we can do the same thing with negative Z-coordinate.
    Basically you need to add the following to the coordinates of your central vertex:
    Code (csharp):
    1.  
    2. (-1,0,0), (1,0,0)
    3. (-1,0,1), (0,0,1)
    4. (-1,0,-1), (0,0,-1)
    5.  
    If your central vertex has an odd Z-coordinate then the first two coordinates (left and right) are the same, but the other ones are shifted one unit to the right:
    Code (csharp):
    1.  
    2. (-1,0,0), (1,0,0)
    3. (0,0,1), (1,0,1)
    4. (0,0,-1), (1,0,-1)
    5.  
    This does the trick for the first circle, but what about the second, third, fifth, ..., n-th circle? That's tricky, but here is how I would do it: As you can see in the above picture we need for each circle degree to get the hexes that are touched by the circle. I'd start with the left- and right-most, then get the ones diagonally until I reach the top (the circle has the shape of a giant hex itself, made of smaller hexes). This means for each circle degree we need one iteration along the Z axis. Once we reach the top we need to close the drawing.
    Code (csharp):
    1.  
    2. // left and right hexes:
    3. leftHex = (-degree, 0, 0);
    4. rightHex = (degree, 0, 0);
    5.  
    6. // we increment the x only on every second iteration
    7. // the initial value depends on whether the central Z-coordinate is even or odd
    8. var x: int = degree - (isEven(centralHex.z) ? 0 : 1);
    9.  
    10. // start the loop
    11. for ( var z: int = 1; z <= degree; z++){
    12.     upperLeftHex = (-x, 0, z);
    13.     upperRightHex = (x, 0, z);
    14.     lowerLeftHex = (-x, 0, -z);
    15.     lowerRightHex = (x, 0, -z);
    16.    
    17.     // increment X if this is an even iteration
    18.     if (isEven(z))
    19.         x++;
    20. }
    21.  
    22. // and now we need to close the drawing
    23. for (var i: int = 1; i < degree; i++){
    24.     missingUpperHex = upperLeftHex + (i, 0, 0);
    25.     missingLowerHex = lowerLeftHex + (i, 0, 0);
    26. }
    27.  
    Hex grids are really tricky because there is always so many possibilities for them. Try to make such an algorithm and tell me if it works. Also, if you don't know how to check whether a number is even or odd, use the modulo operator:
    Code (csharp):
    1.  
    2. function isEven(number: int){
    3.     // return true if it is possible to divide number by two without remainder
    4.     return (number % 2 == 0);
    5. }
    6.  
     
  41. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Fantastic Plugin. Watched all of the videos and Just Bought it. Very nice.

    Was wondering about the polar grid, is there an estimate time that you are thinking about.
    Would like to know because I can better plan the right tool to use for an upcoming project.

    Cheers.
     
  42. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    While learning from the examples, I have a Camera related question.

    I would like to make an in-game level designer and the camera should behave like inside of Unity's Editor.
    Currently, I am using MasterCamera asset from unity store to manage the camera angles.

    1. Can I use more than one camera setup and still have the blocks being snapped to the right location.

    Can you suggest the best way to do this.

    Many Thanks.
     
  43. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    To be honest when I mentioned polar grids it was pretty much just brainstorming, but it shouldn't be hard to do, certainly easier than hex grids. The only problem will be rendering circles, Unity can only render lines (or quads), so the circle would have to be made of a lot of tiny line segments. The circle smoothness (how many segments to use for a circle) will be set by the user. Obviously many smooth circles will tank perormance, in those cases it would be better to use tricks like drawing circles on a texture and using that instead.

    Don't take this as a promise, but I might have something working up by the end of the week (plus how long it takes for Unity to approve the download, can be hours or days, it depends).

    Block snapping depends on the grid's world position inside the scene, not the camera. The camera is only needed for rendering the grid, i. e. making it visible to the player, but it doesn't affect the functionality of the grid in any way. In fact, grids are infinitely large, so they stretch beyond what's being rendered on the screen. However, you need some way to translate a player's mouse input into Unity's world coordinates. The example i provided only works at a very specific angle, so you shouldn't just copy-paste it. I just wanted to use something simple, because mouse input handling was not what the example was about.

    The most common way to translate mouse input to world coordinates is to shoot a ray (raycasting) from the cursor into the scene and take the first point it hits as the point the user is pointing at. This only works if there is something to be hit, like a terrain or a plane.
     
  44. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Great, I got it working. Thanks for the tip.
     
  45. yuewahchan

    yuewahchan

    Joined:
    Jul 2, 2012
    Posts:
    309


    As show in the screenshot, when I drag the car with rotation, it snap to wrong position.
     
    Last edited: May 2, 2013
  46. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    Could you please tell me what the scale of the car's Transform is? Is the pivot point at the centre of the car? Does this still happen if you replace the car with a block (from Unity's primitives) that occupies the same space?
     
  47. yuewahchan

    yuewahchan

    Joined:
    Jul 2, 2012
    Posts:
    309
    Actually, I modified the code a little bit that passing scale ( 2, 0, 1 ) to the AlignVector3 instead of using the localScale, the pivot point is at the centre of the car.
     
  48. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    It is not a good idea to modify my source code, it can make updates more complicated. You should make an extension method instead, same result, but it's inside a separate source file:
    Just copy-paste the method you want to use, rename it and then make your changes.

    I think I know what's going on (this is just guessing, so please correct me if I'm wrong): if an object's scale on one axis is odd the centre needs to be inside a square, but if it's even it needs to be between two squares. When you rotated your car you did not change the (2, 0, 1) vector, thus the calculation still assumes that the car's X is even and the Z odd, so the X gets placed on an edge and the Z on a centre. Swapping the X and Z components of your vector should do the trick.
     
  49. yuewahchan

    yuewahchan

    Joined:
    Jul 2, 2012
    Posts:
    309
    In the example of Runtime Snapping scene, is it possible to not using localScale to represent the 1x2 cube, but a 1x2 mesh cube ?
     
  50. hiphish

    hiphish

    Joined:
    Nov 13, 2010
    Posts:
    626
    Let's see, the Mesh class has a bounds variable, you could use that instead of world scale.

    The AlignTransform method uses AlignVector3 internally and AlignVector3 needs some sort of "scale" to know how "large" the vector is (because of the odd/even question discussed above). How about instead of using AlignTransform you use something along these lines instead:
    Code (csharp):
    1.  
    2. GFGrid myGrid;
    3. Mesh myMesh = GetComponent<MeshFilter>().mesh;
    4. transform.position = myGrid.AlignVector3 (transform.position, myMesh.bounds.size);
    5.