Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by viralvector_games · Nov 20, 2012 at 03:20 PM · pathfindinggrid

Grid Generation

I am developing a pathfinding system for a game. It works, it's clean, and fast. It's works of a grid. Now I am going back to try and speed up my grid generation. As now I am instantiating a number of nodes and placing them. I need it this way so I can select individual nodes. Problem is if I generate a grid bigger than 32x32 unity hangs, a grid that is 100x100 pauses unity for at least 2 minutes. Anyway I can generate a grid of that size with little to no slow up, or at least unity not hanging until it is done.

 for(var y : int = 0; y < gridSizeZ; y++){
         for(var x : int = 0; x < gridSizeX; x++){
             pos = Vector3(parentObj.transform.position.x + x,parentObj.transform.position.y,parentObj.transform.position.z + y) * gridSpacing;
             clone = Instantiate(nodeObject.gameObject,pos,parentObj.transform.rotation).GetComponent(PathNode);
             clone.SetRadius(nodeRadius);
             graphNodes.Add(clone);
             clone.graphID = this.GetInstanceID(); //Tell the node which graph it belongs to
             clone.iD = this.GetInstanceID()+clone.GetInstanceID(); //Give Node an ID
             clone.gameObject.name = clone.iD.ToString();
             clone.transform.parent = parentObj.transform;
             //Check Right
             clone.CheckForNeighbor(Vector3.right,(gridSpacing *2));
             //Check Left
             clone.CheckForNeighbor(-Vector3.right,(gridSpacing *2));
             //Check Up
             clone.CheckForNeighbor(Vector3.forward,(gridSpacing *2));
             //Check Down
             clone.CheckForNeighbor(-Vector3.forward,(gridSpacing *2));
             //Diagonals
             clone.CheckForNeighbor(Vector3(1,0,1),(gridSpacing *2));
             clone.CheckForNeighbor(Vector3(-1,0,-1),(gridSpacing *2));
             clone.CheckForNeighbor(Vector3(-1,0,1),(gridSpacing *2));
             clone.CheckForNeighbor(Vector3(1,0,-1),(gridSpacing *2));
         }
         scanProgress += progressPer;
     }


 //SET RADIUS FUNCTION
     function SetRadius(rd : float){
         transform.GetComponent(SphereCollider).radius = rd; size = rd*.5;    
     }
 //Check Neighbor
     function CheckForNeighbor(direction : Vector3,length : float){
         var hitObj : RaycastHit;
         var nodeObj : PathNode;
         if(Physics.Raycast(transform.position,direction,hitObj,length,1 << 17)){ // Only Certain Path Layer
             nodeObj = hitObj.transform.GetComponent(PathNode);
             if(nodeObj.graphID == this.graphID){//Node we found is in our graph 
                 AddNeighbor(nodeObj); nodeObj.AddNeighbor(this);
             }
         }
     }
 
Comment
Add comment · Show 7
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image CodeMasterMike · Nov 20, 2012 at 03:31 PM 1
Share

Can you show us your code for generating your grid? $$anonymous$$aybe we can help you to find what can be changed for the better.

avatar image viralvector_games · Nov 20, 2012 at 03:43 PM 0
Share

I am not home to pull the code. So when I get back I will post the grid code. But what I am doing is two nested for loops followed by a single loop. In the nested loop I instantiate a node to position, add it to a list, parent it, set collider radius. Then I loop through all the nodes to get their adjacent nodes. But I just realized I can void the last loop and just check for adjacent nodes during instantiation loop.

avatar image viralvector_games · Nov 21, 2012 at 12:30 AM 0
Share

code is up. any clues?

avatar image AlucardJay · Nov 21, 2012 at 05:17 AM 0
Share

Everything is happening in that loop! First thoughts were the instantiate and GetInstanceID, but it also depends on what is happening in SetRadius and also CheckForNeighbor (hope there's no .magnitude in there!). For a first suggestion, do all your calculations first, then in a new loop, cycle through the array and instantiate then. It's ok, when learning meshes I instantiated alot of spheres at vertex points so I could see I got the calculations right. Just think this may be one lag. If there are Debug in the other functions called then this also really slows down if you don't include some kind of yield after the debug log. Just 2 things that will jam up the process.

I think the general answer here is going to be "there has to be a better way"

(after the other functions were added) .... and a GetComponent in both the other functions! You seriously need to look at what you're doing, and find a better way, sorry.

I'm just saying, for 100x100 times, you have 1 instantiate and 9 GetComponents (and 2 GetInstanceID)

avatar image viralvector_games · Nov 21, 2012 at 05:44 AM 0
Share

I have included the set Radius & Neighbor check. $$anonymous$$aybe the issue is that i am using physical nodes, rather than creating instances of a "node" class. If i do change I will need a way of finding neighbors & figuring out what node the player & ai are currently touching without scanning the whole grid

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by CodeMasterMike · Nov 21, 2012 at 07:06 AM

Under normal circumstances, using a grid for A* you wouldn't need to create objects. I would use either a position or a Rect instead. But maybe you need actual grid with objects in your project?

Just generally looking at the code, I feel that the "CheckForNeighbor"-function is unecessary. If you want to know which neighbours a node has, you can more easily check it using the knowledge how long and wide the list is.

ex.

 var gridSizeX = 10;
 var gridSizeZ = 10;
 var totalGridSize = (gridSizeX * gridSizeZ);
 
 for(var y : int = 0; y < gridSizeZ; y++)
 {
     for(var x : int = 0; x < gridSizeX; x++)
     {
         // Create clone and set its properties and whatnots...
         
         // Get node neighbours     
         var thisNodeIndex = (y * gridSizeX) + x;
         
         var downNeighbourIndex  = (thisNodeIndex - gridSizeX);
         var upNeighbourIndex    = (thisNodeIndex + gridSizeX);
         var leftNeighbourIndex  = (thisNodeIndex - 1);
         var rightNeighbourIndex = (thisNodeIndex + 1);
         
         if(upNeighbourIndex >= 0)
         {
             // save neighbour index or object
         }
         if(downNeighbourIndex < totalGridSize)
         {
             // save neighbour index or object
         }
         if(leftNeighbourIndex >= 0)
         {
             // save neighbour index or object
         }
         if(rightNeighbourIndex < totalGridSize)
         {
             // save neighbour index or object
         }    
         
         // add created clone to list...
     }
 }

Obviously some indices/objects doesn't exist when doing the check since they arent created (yet), so thats why I would save the index instead of the actual object.

This is just a example code I wrote fast without testing or optimizing, so it might not be functional, but it gives an idea of what I mean. Hopefully :-)

Good luck!

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image viralvector_games · Nov 21, 2012 at 07:13 AM 0
Share

Thank yo! that is what i am doing now using a multi-dimensional array and a pathnode class. no instantiation,or complex check neighbor, just storing vector offset and array indexes. one problem i would have with this approach is how would i track ai & player position (nearest nodes) without continually scanning grid. Before i was using collision checking with the physical nodes.

avatar image CodeMasterMike · Nov 21, 2012 at 07:23 AM 0
Share

Well, I think checking collision on physical nodes continually would be, as equal or maybe even more expensive, than run through a list (remember to exit the loop as soon as you found the right node!).

Using A* you should have a closed list with the nodes the object is using and that list is shorter than the grid orginal list.

If you aren't using the A* then maybe you don't need to scan the grid every frame to save some work.

avatar image viralvector_games · Nov 21, 2012 at 07:42 AM 0
Share

ok i must have mistyped. ai Players & main user have a class that does a physics overlap-sphere on their current position with a layer-mask to only check for nodes. the actual nodes are not making the check it would be 10000 nodes doing physics constantly versus 10 characters. In the same aspect on avg cost doing a scan of all nodes to do a figure out which node the user is next to would be ---> O(numberofusers numberofnodes/2) = with 10 users and 10000 nodes = 10 500 = Expensive. I get what you mean by closes list and yest i am using a*..but this could only work for ai not the main-player which does not use the pathing system so i would still need to know which node the player is closest to

avatar image CodeMasterMike · Nov 21, 2012 at 07:59 AM 0
Share

Ok. $$anonymous$$aybe you can do something like this :

At startup you get the node (and its index) where all individual player is standing. $$anonymous$$aybe Run through the loop once but check all players at the same time to avoid running the loop once per player.

And each update/frame, you check the player towards this node that you have currently stored. The check can include if the player is closer to this node or to any of its neighbour nodes, and update the current node accordingly. This should shorten the check for you.

So that would be 10 users checking maximum 5 nodes each = 50 nodes per frame.

avatar image viralvector_games · Nov 21, 2012 at 09:02 AM 0
Share

ok i see what you mean. I was able to do use the multidim array and grid generates in less than a second now. so issue resolved. Now i just have to re-integrate everything. i will report on if your solution was quick enough, or something else i used.

avatar image
0

Answer by sparkzbarca · Nov 21, 2012 at 07:17 AM

i'm not trying to be dispiriting but is there a reason your not using the established pathfinding solutions?

NavMesh A* etc?

I mean fast pathfinding code isn't exactly something you stumble apon. :P

If your doing it because you'd rather have your own I guess so it's just that I mean i've no idea how to create unity or nividia phsyx or a number of other highly technical specialized set of code functions. That's why I leave it to the experts. :P

You could spend the next month coding that and it'd be way slower than the implementations already available out there with less functionality.

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image viralvector_games · Nov 21, 2012 at 07:31 AM 0
Share

As a response,and not being snarky, but with that kind of attitude no one would ever innovate anything, or re-innovate the wheel & make it better. But to answer your question, i am developing a project and i want the entire project in house. I am a code enthusiast so i enjoy the challenge and do not want to wait for another individual to work on their project for me to update $$anonymous$$e with features(and i do not want to spam a feature request forum).if i did use another's pathing the geek in me would eventually want to make my own, so there is no point in wasting time learning others' code. $$anonymous$$y implementation is fast with avg computation time of .001 ms for paths of 38+ nodes. I am using 1. my own $$anonymous$$ heap, 2. dictionary 3. hashtable to keep all operations O(1)-O(logn) all in unity-script (will port to c# once i get it working). also most packages out there do not support multifloor grid-graphs (easily) & my implementation does it easily. But most importantly i am creating this so other people that i work with can utilize a system that is built in house. Plus its just fun to overcome a difficult task. :)

avatar image sparkzbarca · Nov 21, 2012 at 08:15 AM 0
Share

You get the source code with the free A* you can add your own features. your implementation is much slower than free A* which searches 1k nodes per millisecond. If you enable multi threaded support it can search 4.5k nodes with a 4 core proccessor.

It supports multifloor grid graphs

Don't get me wrong the A* algorithm already existed and so it was remade for unity and improvements were probably made during the reinvention etc.

Reinventing to improve is fine if that is your project. But your project is a game not a pathfinding algorithm. I mean you didn't re-invent a program$$anonymous$$g langauge or a game engine. :P You used what was already supplied.

I'm only saying this because I think it would suck for you personally if you ended up spending months on a pathfinding algorithm ins$$anonymous$$d of on the game and didn't get as many features into the game.

And what if your algorithm isn't efficient enough because you add more agents or nodes, you'd have to dump it all for the A* so you could have a game that had a playable framrate?

It's just that in highly specialized fields its best to leave it to the experts. People often try to create there own custom encryption algorithms, the result is stuff that is far less secure than using the universal standards of encryption. You can try and create your own physics simulations using transform and functions but its going to be way worse that trusting nvidia Physx.

If it works it works but remember there are also downsides to trying to a master of all. :P $$anonymous$$onths spent on pathfinding aren't spend on other features or code.

avatar image viralvector_games · Nov 21, 2012 at 08:57 AM 0
Share

Well i am not making a game. This is the last thing i am focusing on in my project. I still have to make improvements but i am willing to spend a month on it, it would be another thing if i was program$$anonymous$$g illiterate and had no knowledge of data structures, run complexities, other search & sort algorithms,etcs. I want to learn so i can be an "expert". For instance path-finding is subjective in a way by the way you can calculated heuristics & deal with tie-breaking, path smoothing, and dynamic obstacle avoidance. I want a solution that is molded for my projects & can handle multi-floor graphs + graph linking methods, dynamic obstacles(reason why my implementation is slower as i scan each node for obstacles before i add it to open list). Anyway i don't want to be a developer that does not know exactly what is going on and know how to alter every piece of code in any of his projects. Don't get me wrong i used A* project to make & publish an iOs fps last year, it is a great package, and i was able to learn other things while using it. now it is time for me to tackle pathfinding, put it all together and i will have a great engine i can use for any project in the future. Sorry for the long winded response. :) i am a nerd at heart so i get passionate with subjects of such

avatar image sparkzbarca · Nov 21, 2012 at 04:23 PM 0
Share

nope A* is dynamic collision detection so it scans too. :P

600 agents with randomly placed obstactles spawning every few tenths of a second http://www.youtube.com/watch?v=htoen7x3LuQ

$$anonymous$$y guess is you should look at the source code for node generation/storing on the A* program for a faster implementation of node generation.

I will note that they use Cached implementation.

If each level starts out the same, take the time to spend 2 $$anonymous$$utes yourself calculating each levels nodes and then store that array with the scene, Then you can retrieve that at the start of the scene from then on with no hang/load time.

avatar image SpaceManDan sparkzbarca · Dec 27, 2018 at 04:09 PM 0
Share

This is exactly what i'm trying to do but I have no idea how to store and load my array. I'm not asking for code, but a point in the right direction for how to do this would be greatly appreciated.

$$anonymous$$y array is 3d and stores 9,375,000 nodes. So it takes several $$anonymous$$utes to generate.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

13 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Best approach to generating a grid for basic A* pathfinding 1 Answer

Astar Pathfinding not scanning graph 0 Answers

TBS - Suggestion (Beginner) 0 Answers

grid pathing system 1 Answer

PATHFINDING in a grid game 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges