Search Unity

[v1.4] Node Map - Node-based maps made easy

Discussion in 'Assets and Asset Store' started by Schneider21, Jul 27, 2017.

  1. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Hey, @StevenWendel! Thanks for the interest! There's no reason I can think of that NodeMap shouldn't work in 5.6. I just went with 2017.1 because it was the version I was currently on, and maintaining multiple installs of Unity has always been, in my opinion, annoying. Kinda makes me hate the way Unity handles version stuff for the Asset Store... In my perfect world, the asset package would be scanned for API methods, shaders, or included built-in classes to determine the minimum compatible version.

    Anyway, something about your username is sticking out in my mind as being someone I'm a fan of, so I'll download 5.6 and try doing an export to get that need met for you! If I haven't posted back here by tomorrow afternoon, harass me again as a reminder. :p

    - - -

    To everyone else, I haven't forgotten about this asset or the updates I mentioned! Things have been pretty busy the last 2 months with the new little guy. He's really good, but it's just crazy how much a second child seems to change the situation enough to sap all your energy away. But we're starting to find our rhythm again, and I'll be able to put some time in again nights where I don't pass out too early.

    Performance / bugs get priority, and then it'll be getting that line-renderer option added.

    Additionally, thanks to everyone who's purchased so far! It's not enough to quit my day job yet, but we've got enough for some diapers, anyway!

    Edit: Nevermind, Steven, that was easier than I thought it'd be... Got 5.6 installed and managed to bring the project up with it okay. Had some weird lightmap-related errors, and a single editor crash, but the demo scene ran perfectly afterwards. Uploaded and submitted for review. I'll let you know once it's approved and available!
     
    Last edited: Nov 27, 2017
  2. superwendel

    superwendel

    Joined:
    Jun 18, 2013
    Posts:
    105
    My username is just my name. Maybe you're just a fan of me? :p
    I thought about just giving it a shot myself but I'm happy you made the export for me (and maybe some quiet others!)

    And it's currently part of the sale? I feel very lucky at the moment. Thank you! I can't wait to integrate this into my project.
     
  3. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Ha! Maybe?!

    Honestly, it was foolish of me to have only exported it for 2017, especially given how easy it was to open and re-export. Thanks for speaking up!

    Gosh, you're right! What a great time to buy! :p You hear that, everyone? Buy, buy, buy!
     
  4. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    @StevenWendel The 5.6-compatible version is now available on the Asset Store. Give it a shot (assuming that recent purchase was you...) and let me know if you have any problems with it.
     
  5. superwendel

    superwendel

    Joined:
    Jun 18, 2013
    Posts:
    105
    That was quick, The Asset Store wasted no time in accepting that!
    It was me that made the recent purchase. I knew the version was coming and wanted to lock in that sale price. :)

    This is very nicely set-up and easy to get going. The documentation is also well written and entertaining.
    "Delete - Self-explanatory. Say goodnight, Node!" <-- Made me actually laugh.

    A quick question, is there already a way to make it so that the agents do not rotate when moving towards a node? My use case is for a 2D overworld and I essentially want my characters to always stand upright when traveling from node to node.
     
  6. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    I know, right? Considering it took them an entire month to approve it the first time around, I'm pleasantly surprised!

    Thank you! Glad you got it at a discount rate!

    Writing the documentation took almost as long as creating the asset itself! I did try to have fun with it a bit, and I'm very happy it was appreciated.

    Yeah, my solution kinda assumes the simplest case of looking at and moving towards, but probably a bit of an oversight on actual use cases.

    If your sprite doesn't need to turn at all, you can add this line after Agent.cs:108:
    Code (CSharp):
    1. transform.LookAt(Camera.main);
    That would be like Super Mario Bros. 3 where the sprite just kinda slides around. If you want something a bit more Final Fantasy-like, with facing left or right as appropriate, add the line above and also:
    Code (CSharp):
    1. transform.scale.x = (curWayPoint.x > transform.position.x) Mathf.Abs(transform.position.scale) : - Mathf.Abs(transform.position.scale);
    That assumes your sprite scale is not (1,1,1). If it is, you can simplify that line to:
    Code (CSharp):
    1. transform.scale.x = (curWayPoint.x > transform.position.x) 1 : -1;
    This also assumes the X axis is still your horizontal axis, by the way. This is untested code, so give it a shot and let me know if it works for you!
     
  7. superwendel

    superwendel

    Joined:
    Jun 18, 2013
    Posts:
    105
    Adding the line
    Code (CSharp):
    1. transform.LookAt(Camera.main.transform);
    After 108 still has the agents rotating, just now slowly and in a funny way. (Main.camera didn't work, I assume you wanted to point to the transform of camera)
     
  8. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Yep. I forgot to type out the transform part.

    Also, I'm an idiot. MoveTowards has nothing to do with rotation. Get rid of all the crap I told you to add today and just comment out lines 206, 221, and 294. The scale changing line from before could still be useful if you want to flip the left and right facing.

    Sorry for the confusion!
     
  9. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    @StevenWendel Whoops, forgot to tag you so you got the alert. See previous post.
     
  10. superwendel

    superwendel

    Joined:
    Jun 18, 2013
    Posts:
    105
    Works perfect now! Thank you for such prompt responses. I'll come back here if I have any other questions that come up.
     
    Schneider21 likes this.
  11. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    No problem. Happy to help! Don't forget to post back here with some shots of your progress!
     
  12. sirealparadox

    sirealparadox

    Joined:
    Aug 26, 2017
    Posts:
    1
    I'm make a 2d top down game where the Node Map is the actual Map in the game to travel to different locations. I need scenes to load on collision but it appears the nodes have 3d box colliders and on trigger events are not registering. Am I doing something wrong?
     
  13. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Hi, @sirealparadox! While the nodes do have colliders on them by default, I don't think I use them for anything out of the box.

    Node Map events are triggered within the Agent class. If you want to load a new scene when an Agent arrives at a Node, you'll register the OnNodeArrive event. Check out the AgentControls script in the Demo folder for an example of how to subscribe to that event.
     
  14. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Just a little update to reassure people that I'm still working on things.

    I've looked into adding solid lines using Unity's LineRender as @rmdd suggested. I think that'll be a fine way to go! I've kinda waffled on what the best implementation should be, and I'm open to any input on that front.

    Should Markers and Lines be exclusive options, or both able to be used simultaneously?
    I can see the benefit of having markers that aren't visible (for their events) while using the solid lines as the rendered portion, so I'm leaning towards that route. It also makes retrofitting them in a bit simpler. The only real advantage I see for having them be separate would be that it might be less confusing for new users since it'd show less configuration options at any given time.

    I'm also thinking I should share some settings to keep things less complicated all around. So, for example, the distance between markers would be the same value used for how long a segment of the line renderer is. This has the benefit that if you have both turned on, the lines will always follow the same path as the markers.

    @rmdd also brought up performance issues with large numbers of Nodes. One idea I had to mitigate this is to ensure all Nodes and Markers are static. So I've added that to the code to instantiate them in that way (since, ostensibly, you wouldn't be moving Markers or Nodes at runtime anyway). This seems to work fairly well for me. A scene with 200 Nodes and probably around 1000 Markers ran at just under 60 FPS on my decent-but-not-gaming-rig work machine.

    If anyone's experiencing these performance issues, try toggling your Maps to static to see if that helps. Make sure you don't have your Agents set to static, though, of course. The automatic static initializing will be rolled out in the next update.

    Finally, an appeal to those who have purchased:
    If you've purchased this asset and enjoy it, please take a bit of time to review it. More reviews help give the asset more exposure, which helps get it in more hands. And the more people relying on my code for their games, the more it pushes me to improve it!

    If you've purchased and you're not 100% happy with it, please reply in this thread with what issues you're having or what features you'd like to see added or improved. I take all feedback to heart and will do my best to make this asset a must-have!

    Both of my kids have been sick lately, which translates to me just being exhausted at the end of the day, but I'm finding a bit of time here and there to work. So while progress has been a bit slower than I'd like, it is moving along.

    - - -

    Stay tuned for more concrete info soon!
     
  15. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Line-based paths progress is moving right along!



    Thanks again to @rmdd for the LineRenderer suggestion.

    This system will easily translate to curved lines once I add that in. Before digging into that, though, I want to get this option pushed out to everyone, since I feel like it's something a few people have been looking forward to. I have to do something about rendering order to make sure lines always render below Nodes so there's no Z-fighting. Then just clean up a few settings in the custom Inspectors, update the documentation, and it should be good to go.
     
  16. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Version 1.1 is now available for download!

    Changelog:
    • Added option to render Paths as Lines
    • New objects are instantiated as Static to improve runtime performance
    • Changed Create Path keyboard shortcut from CTRL+P to CTRL+J to avoid conflicting with Windows “Play” editor shortcut.
     
  17. rmdd

    rmdd

    Joined:
    Aug 17, 2014
    Posts:
    3
    Cool. Can't wait to play with this!
     
    Schneider21 likes this.
  18. luthfirian

    luthfirian

    Joined:
    Mar 5, 2013
    Posts:
    7
    Hai All,
    Any update making Line Renderer with this plugin ?
    start from start point and end at end point
     
  19. luthfirian

    luthfirian

    Joined:
    Mar 5, 2013
    Posts:
    7
    Sorry I didnt Read this Update "New in v1.1: Option to render line between nodes", i think i will try this
     
  20. luthfirian

    luthfirian

    Joined:
    Mar 5, 2013
    Posts:
    7
    Good Asset and good documentation,
    but, I want ask about Line Renderer, when i try to enable Draw Line, it is just draw on One Path.
    is there a way to bring up a active Line Renderer between start Node to target Node when Im in ClickAgent mode ?
    sorry for bad english, but i hope u can understand :)
     
  21. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Hey, @luthfirian! Thanks for the purchase!

    If I'm understanding you correctly, you'd like to highlight the route an agent will take when navigating through a series of nodes towards an endpoint, correct?

    I don't currently have that built in. I'll add it to the ToDo list of things to look into adding, though.

    In the meantime, if you're able to write a bit of code yourself, I'd start with using the static Pathfinding.FindRoute method to get a list of Nodes. Then use the transform property of those Nodes to render lines how you like. I'd make sure to drop the first item in the list, though, and use the transform of the Agent for your first line, that way it doesn't render behind where the agent has already traveled.

    Please let me know if I'm on target with what you're looking for, and don't hesitate to reach back out for further assistance!
     
  22. alex_unity840

    alex_unity840

    Joined:
    May 6, 2018
    Posts:
    6
    Hi All,

    I have an agent and a several nodes, one of which has an extra c# script component (agent = car, one of the nodes is the `workshop`).

    I want to detect when the agent arrives at a node with the type 'workshop'. I can see in the API that there is the 'OnMoveEnd' event, But I can't seem to hook this up correctly.

    I feel like it should be something like...

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using JSNodeMap;
    4.  
    5. public class AgentMovement : MonoBehaviour {
    6.  
    7.     public Agent agent;
    8.  
    9.     private void Awake() {
    10.         agent = GetComponent<Agent>();
    11.     }
    12.    
    13.     private void Start() {
    14.         JSNodeMap.Agent.OnNodeArrive += DoSomething;
    15.     }
    16.  
    17.     public void DoSomething(){
    18.         Debug.Log("something wonderful?");
    19.     }
    20. }
    21.  
    But this just won't compile.

    Any suggestions on how to write the code to listen for that event would be greatly appreciated.

    Some more examples of using the api in the docs would massively help
     
  23. alex_unity840

    alex_unity840

    Joined:
    May 6, 2018
    Posts:
    6
    How ruddy exciting, on posting this I

    Code (CSharp):
    1. using UnityEngine;
    2. using JSNodeMap;
    3.  
    4. public class AgentMovement : MonoBehaviour {
    5.  
    6.     public Agent agent;
    7.  
    8.     private void Awake() {
    9.         agent = GetComponent<Agent>();
    10.     }
    11.  
    12.     private void Start(){
    13.  
    14.         agent.OnNodeArrive += HandleNodeHandlerBool;
    15.  
    16.     }
    17.  
    18.     void HandleNodeHandlerBool(Node node, bool target)
    19.     {
    20.         if (node.nodeType == 1)
    21.         {
    22.             Debug.Log("Arrived at workshop");
    23.         }
    24.     }
    25. }
    26.  
    Can anyone help on how to convert the node.nodeType to the node name? just to make it easier to read in the code
     
  24. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Hey, @alex_unity840!

    This is a great example of something that should be added to the plugin. I'll add it to my list.

    In the meantime, you can work around it by doing something like this:

    Code (CSharp):
    1. int workshopTypeIndex;
    2.  
    3. void Awake () {
    4.     workshopTypeIndex = GetNodeTypeIndexByName ("Workshop");
    5. }
    6.  
    7. public int GetNodeTypeIndexByName (string typeName) {
    8.     return System.Array.FindIndex (agent.nodeMap.nodeData.nodeTypes, nodeType => nodeType.name == typeName);
    9. }
    10.  
    11. void HandleNodeHandlerBool (Node node, bool target) {
    12.     if (node.nodeType == workshopTypeIndex) {
    13.         Debug.Log ("Arrived at workshop");
    14.     }
    15. }
    Let me know how that works for you!
     
  25. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    @alex_unity840

    I've added some helper functions to be able to more easily compare Nodes, Markers, and Agent types. These will roll out in the next update (once I tick a few more of these issues from my ToDo list), but if you want to use them now, just add the code below inside the Map.cs class file.

    Code (CSharp):
    1. public int GetNodeTypeIndexByName(string typeName) {
    2.     return System.Array.FindIndex(nodeData.nodeTypes, t => t.name == typeName);
    3. }
    4.  
    5. public int GetMarkerTypeIndexByName(string typeName) {
    6.     return System.Array.FindIndex(nodeData.markerTypes, t => t.name == typeName);
    7. }
    8.  
    9. public int GetAgentTypeIndexByName(string typeName) {
    10.     return System.Array.IndexOf(agentTypes, typeName);
    11. }
    12.  
    13. public bool IsNodeType(Node node, string typeName) {
    14.     return node.nodeType == GetNodeTypeIndexByName(typeName);
    15. }
    16.  
    17. public bool IsMarkerType(Marker marker, string typeName) {
    18.     return marker.markerType == GetMarkerTypeIndexByName(typeName);
    19. }
    20.  
    21. public bool IsAgentType(Agent agent, string typeName) {
    22.     return agent.agentType == GetAgentTypeIndexByName(typeName);
    23. }
    I want to add the ability to more easily show the path an Agent will take to get to a route. Since there are so many different ways this can be done, and all would depend on your specific art style, I think what I'll have is a method that returns a list of Transforms, with the first item being the Agent's current position. This way you can call it once to just draw a static representation, or call it repeatedly if you want to update the graphic as the Agent moves.

    If anyone has other ideas on how they'd like to see this implemented, I'm all ears!
     
    alex_unity840 likes this.
  26. alex_unity840

    alex_unity840

    Joined:
    May 6, 2018
    Posts:
    6
    Sorry I missed these the other day, I haven't been getting notifications for some reason. However, those helper functions look great.

    Sounds perfect, I'd be very keen to use that.

    Expanding the helper functions to include a few more actions would be very useful...

    Find empty node. Return the nearest node which is currently unoccupied, this would be very useful for spawning new agents on the fly as it avoids the potential clash with other agents. If no empty nodes are found, simply returning false or null

    Find empty node of type
    Same as above, but setting a type would also be useful if you wanted to have specific spawn points.
     
  27. alex_unity840

    alex_unity840

    Joined:
    May 6, 2018
    Posts:
    6
    In addition to this, not sure if this would be a new feature or just me not understanding the docs, how do you tell if an agent has a node... or a node has an agent?

    I'm currently using the OnNodeArrive event to dummy this up, but can't seem to find any specific functionality to do something like...

    Code (CSharp):
    1. Agent[] agents = FindObjectsOfType<Agent>();
    2. Node[] nodes = FindObjectsOfType<Node>();
    3.  
    4. foreach (Agent agent in agents)
    5. {
    6.     foreach (Node node in nodes)
    7.     {
    8.         // nodeType 0 = basic;
    9.         // nodeType 1 = Garage
    10.         if (node.nodeType == 1)
    11.         {
    12.             if (node... is empty)
    13.             {
    14.                 // Send the agent to the garage
    15.                 agent.JumpToNode(node);
    16.             }
    17.         }
    18.     }
    19. }
     
  28. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    @alex_unity840 Great suggestion with the additional helpers. I'll get to work on them immediately. Stay tuned.

    As far as identifying whether a Node has any Agents or if an Agent is at a Node, I didn't have a nice clean way built in, so I just added this. For a Node, you'd access its "agentsAtNode" property, which will return a list of all Agents that are currently occupying that Node. For Agents, you'd use its "currentNode" property (this previously existed, but was also used for the last Node that Agent was on... it's been separated into separate values now).

    I'm sure your example is a bit contrived, but please never access Nodes or Agents (or anything, ever) by using FindObjectsOfType<>(). Instead, in your script, assign a reference to the top-level Map (or find that with code, if you have to) and use the Map's "mapNodes" and "mapAgents" properties.

    Does that make sense? If you want to get more specific with the example as it applies to your needs, I'm down.
     
  29. alex_unity840

    alex_unity840

    Joined:
    May 6, 2018
    Posts:
    6
    Yea that makes perfect sense, I've updated my code to avoid FindObjectsOfType

    The new agentsAtNode features sound perfect, thank you so much!
     
  30. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Code is all written. Just have to update the documentation and then I can republish and submit to the Asset Store.
     
  31. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
  32. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    853
    Hi @Schneider21

    From your documentation I get the impression that nodes and paths can also be created programmatically at runtime?
     
  33. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Absolutely.

    You can run the Map's CreateNode method to create a new Node. That method returns the Node reference for setting things like its name, position, and type. I could probably provide some overloads for allowing you to define them explicitly instead, but it was one of those things that I just didn't know how granular people were going to get with it, so I didn't want to waste the time and effort until it was needed.

    You can get Nodes by name if need be by using GetNodeByName. You can use a Node's CreatePath method and pass in another Node to create a Path between them (which again, returns the Path reference for setting additional properties).

    If you try messing around with it and find features that would make it more user friendly, let me know and I'll add them in!
     
    c-Row likes this.
  34. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    853
    Great - procedural star map incoming. :cool:
     
    Schneider21 likes this.
  35. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Yes! And for real, let me know as you go if there's anything I can add to the asset to make it easier on you!
     
  36. dibdab

    dibdab

    Joined:
    Jul 5, 2011
    Posts:
    976
    hello Justin,

    need a bit of advice / thoughts on this. I'm thinking about making traffic paths, and connecting node paths

    it's possible to have more instances of NodeMap in the project and I could get the Map.cs (in the root transform of nodes, when my vehicle registers a node by its trigger)
    but
    the pathfinding method is static: Pathfinding.FindRoute(startNode, targetNode) - shouldn't this be unique?
    (the nodes are unique, as all have their paths defined on them)
    and
    when I want to join paths, how would that affect the pathfinding
    (I dont want vehicles to travel/choose path on a wrong lane) like in this case from 22 to 5, on right-hand traffic roads
    roadnodes.jpg
    also the path only appears on one of the nodes (the opposite direction as intented) see attached


    or can I make this with one NodeMap and one-way path direction?
    I'll have to download 1.2 as every path seems to be two-way in 1.1 (apart from when two nodeMap nodes are connected)
     

    Attached Files:

    Last edited: Oct 25, 2018
  37. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Hey, @dibdab! Thanks for the purchase!

    The Nodes contain a reference to their parent NodeMap, so calling FindRoute can be called on a set of Nodes when there are multiple NodeMaps without problem. There's no way to move between two separate NodeMaps, though, so if you want the systems to connect, they should all be within one NodeMap. The idea of allowing multiple NodeMaps in a scene would be to have two separate systems going.

    In your case, I would make sure every single path is set to be one-way, moving in the direction of the lanes. Changing your markers to the arrow icons would help visualize that better, too. Your paths can overlap each other, so have that bottom left path connect like this:
    Untitled.png

    Paths are children of the Node they're coming from. For one-way movement, you'll want to ensure that follows the logic for their path of movement. For two-way paths, it's a bit more complex to get neighboring Nodes, but you shouldn't have to deal with that here.

    Does that answer your questions? Let me know if I can clarify it any better.
     
  38. dibdab

    dibdab

    Joined:
    Jul 5, 2011
    Posts:
    976
    I'm a long-time customer :)

    okay, so only one nodeMap.

    where can be changed? I have one-way
    oneway.jpg
     
  39. dibdab

    dibdab

    Joined:
    Jul 5, 2011
    Posts:
    976
    ah okay, I found it. must select path (on the node)

    but does it have to changed manually for all paths?

    this looks like a bug:
    cannot reverse path.
    roadnodes2.jpg
    okay, no bug. have to be reversed by action
    roadnodes2x.jpg


    now again there seems to be a problem to solve
    roadnodes2c.jpg
    I don't want to vehicle to turn back
    (but to follow the straight line)

    overrides would help with that?
     
    Last edited: Oct 25, 2018
  40. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    @dibdab Ah, I thought your username sounded familiar... I suppose in that case, thanks for being a continued user! ;)

    I might have been unclear with my wording, so here's a hastily drawn image to illustrate what I mean.

    paths.png
    The routes you're defining should only intersect where they're merging. In the case of that problematic area, the red branch here should not share a Node with the blue branch except for at the very bottom, where the agent would be traveling straight from west to east. You'll see your markers overlapping where red and blue cross paths, but agents will not be able to jump tracks, if you will, at that point.

    Does that make more sense?

    As far as setting the style for all Paths, if you set the default style for markers in the NodeMap object, all new paths will use that style. Much easier to do early on than to go back and change them all. I didn't come up with a good way to change the default style for existing Paths without overwriting ones you had wanted to be different, sadly.
     
  41. dibdab

    dibdab

    Joined:
    Jul 5, 2011
    Posts:
    976
    I see. yeah, that could work.

    Thanks.
     
  42. Sandman_Ivan

    Sandman_Ivan

    Joined:
    May 6, 2015
    Posts:
    7
    hay great asset but I'm having some problems with an idea.

    So I'm trying to make a pushable block that also act as impassable areas. I have yet to get to the pushable part because. the impassable part is having problems.

    so what I'm doing is I have a block Agent. and the idea is: if the block ISN'T moving, then take the current node it's on, getting all Paths (to and from) and setting an override to stop the player from using that node.

    but my code tends to break, the movement override seems to be overloaded and I don't know how to go around this.


    A small extra question is there any easy way to make a grid pattern setup? it took me a good half hour making a grid for a simple 5X5 square area. Maybe cool as a feature in the future for that but that's just my opinion.


    Side note about my problem, I don't have any code per se, I use BOLT but I can work with your code and willing to use anything to get this to work. I am just not a great programmer.
     
  43. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Hey, @Sandman_Ivan! Thanks for the purchase!

    This is an interesting use case. I wrote a script that would do this, but in doing so I found a bug in the asset!

    Attach this script below to your blocker agent.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using JSNodeMap;
    5. using UnityEngine;
    6.  
    7. public class BlockerAgent : MonoBehaviour {
    8.     private Agent agent;
    9.     private int blockerAgent;
    10.     private int[] nonBlockerAgents;
    11.  
    12.     void Awake () {
    13.         agent = GetComponent<Agent> ();
    14.         blockerAgent = agent.agentType;
    15.         // Non blocking agents is a list of all agent type indexes that aren't the blocker type
    16.         nonBlockerAgents = Enumerable.Range (0, agent.nodeMap.agentTypes.Length).Where (i => i != blockerAgent).ToArray ();
    17.  
    18.         // Subscribe to agent events
    19.         agent.OnMoveStart += BlockerMoveStart;
    20.         agent.OnMoveEnd += BlockerMoveEnd;
    21.     }
    22.  
    23.     void Start () {
    24.         // Call the BlockerMoveEnd here on start location to block paths at start
    25.         BlockerMoveEnd (agent.currentNode);
    26.     }
    27.  
    28.     void OnDestroy () {
    29.         agent.OnMoveStart -= BlockerMoveStart;
    30.         agent.OnMoveEnd -= BlockerMoveEnd;
    31.     }
    32.  
    33.     // When a blocker starts moving, unlock all the paths connected to the current Node it's sitting on
    34.     void BlockerMoveStart (Node targetNode) {
    35.         Path[] unlockPaths = agent.currentNode.GetAllPaths ();
    36.         foreach (Path path in unlockPaths) {
    37.             UnblockPath (path);
    38.         }
    39.     }
    40.  
    41.     // When a blocker stops moving, block all the paths connected to its current Node
    42.     void BlockerMoveEnd (Node destinationNode) {
    43.         Path[] blockpaths = destinationNode.GetAllPaths ();
    44.         foreach (Path path in blockpaths) {
    45.             BlockPath (path);
    46.         }
    47.     }
    48.  
    49.     // To block a path, we'll loop through each non-blocking agent type and create an override preventing their movement
    50.     void BlockPath (Path path) {
    51.         foreach (int agent in nonBlockerAgents) {
    52.             path.AddOverride (agent, MovementType.Impassable);
    53.         }
    54.     }
    55.  
    56.     // Same thing to unblock, but removing the override instead
    57.     void UnblockPath (Path path) {
    58.         foreach (int agent in nonBlockerAgents) {
    59.             path.RemoveOverride (agent);
    60.         }
    61.     }
    62. }
    You'll also have to fix the bug in the code until I can roll out an update. On lines 193 and 206 in Path.cs, change "First" to "FirstOrDefault". I'll update the code and push the patch out as soon as I can.

    Try this and let me know how it works for you. Bear in mind, this won't disallow a blocker and player from moving to the same node simultaneously (and in fact, would end up trapping the player once they both got there), but it's a good start.

    - - -

    As for quickly building a grid, I don't have much in the way of built-in Map generation other than by hand. I do have methods that can be called, but that does require a bit of code knowledge. The quickest way (and what I did to set up this test case) would be to create a line of nodes extended from each other, then select them all and extend them to make the other axis. You'll still have to connect each row as you go, but for a 5x5, that shouldn't take long.

    I'd love to say I'll add in tools to help build that for you, but the specifics of what people would want are so different that it'd be very difficult to create something generic enough to be useful.

    Edit: Update has been submitted to the Asset Store. I'll let you know when the change has been published.
     
    Last edited: Dec 14, 2018
  44. Sandman_Ivan

    Sandman_Ivan

    Joined:
    May 6, 2015
    Posts:
    7
    hay it works like gangbusters! in fact I also tried to put it on my player as well and its great for keeping them solid. you should package up this BlockerAgent as part of the code as its great for faux-physics.

    also your codefix works as well. i dont understand what it did or anything but all of it runs smooth. I am glad i could help shine a light on a bug i didnt know about lol.

    yeah to sum up im useing your nodes as a great grid-but-open puzzle game. so i can use a nice solid area of puzzle solveing then use the nodes to allow the player to go in diffrent places. Kinda inspired by "Lara Croft GO"(link to video) and i think your grid has enough flexability to makes this happen.
     
    Schneider21 likes this.
  45. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Awesome! Glad to hear it!

    I was thinking something like that. I'd probably want to make something a bit more robust that can be configurable (like kicking an Agent back to its previous Node if another blocking Agent arrives at its destination before it, or allowing certain Agent Types to overlap but not others). I'll toss this around a bit and see what I can push into another update. Thanks for shining a light on this and helping to improve the asset!

    I had a helper method that I added but never really tested. I just threw it in there in case someone wanted to add an Override at runtime. But shockingly, the untested code had a problem! That's why I like when people ask these kind of questions and force me to create a working example for them... Gives me a targeted purpose to find issues with the code.

    I'm really interested in seeing what you make with this! I didn't play Lara Croft GO, but I did play Hitman GO and enjoyed that quite a bit. Please keep me updated on your progress!
     
  46. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Node Map has been updated to include the API fix, @Sandman_Ivan.
     
  47. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Node Map has been updated to 1.4. The following issues have been addressed:

    Node Scale
    When I started creating the asset, I had a setting that would set the default size of newly created Nodes. Somewhere along the line, I changed it to be a value that would be used to uniformly set all Node scales. I have no idea why. It turned out that there was an issue that would cause any manually set Node scales to be wiped out upon redrawing of the map (which, incidentally, occurs when entering Play mode and such). So the feature was essentially totally broken.

    Node Scale has been moved to the Default Settings and now only affects the size of newly created Nodes as I originally intended.

    Null Reference Exceptions
    The Node Map object contains references to its child Nodes. Because of this, the "proper" way to delete a Node is through the Node Map Inspector. As the creator, I took this knowledge for granted as a given, and habit caused me to not even think how someone not as intimately familiar with the code would use the asset.

    This meant that deleting a Node (or Path) manually, as you would any other object in Unity, would cause Null Ref Exceptions to flood the console when you have Nodes selected, as the Inspector is trying to access objects that don't exist anymore. I put some code in place to catch these situations and clean up the references, but there's a good chance I missed some cases. If anyone runs into issues with Null Ref flooding, please reach out and let me know the conditions to reproduce so I can fix those, too. I'm looking into better ways of handling the deletion of objects managed in this way, so future updates may avoid this issue entirely.

    Position Handles
    I don't recall this being an issue before, but when I was fixing these other issues, I noticed that any Nodes that had Paths would have their position handles placed at the midpoint for all child objects. This is really unintuitive, so I put a fix in to ensure Nodes always had their position handles at their own position.

    - - -

    As always, I appreciate any feedback, feature requests, bug reports, and of course, Asset Store reviews! I also love seeing what you're building using the asset, so feel free to share and show off as well.
     
  48. vyshan

    vyshan

    Joined:
    Oct 20, 2018
    Posts:
    4
    Hello guys! Just acquired the asset, but I'm having trouble on setting a 2D:
    - I´ve set the map to 2D and created the nodes using the "create node" and "create agent" on the inspector.
    The issues:
    1. For some reason the sprite moves +1 tile X and +1 tile Y (so it moves 1, on diagonal) every time I start the game, and also it doesn´t reset to its original position, any ideas why? (this is happening with all types of movement attached to the agent)
    2. When I use the movements (click, direct etc...) the sprite changes the rotation to 45 degrees X and 90 degree Y while it moves to the next Node, that´s a problem because it disappears from the camera, where can I change that?
     
  49. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Thanks for the purchase!

    In the interest of full transparency, I started this asset with a 3D focus as that's what I usually work with. I added the 2D functionality, but naturally just sort of tested things primarily in 3D. Another customer has been using the 2D mode and reported some issues, and I'm figuring out the best way to incorporate the required changes to make 2D an easier experience.

    1. Since I use Unity in 3D mode, it always made sense to me to represent the map as if it were on the surface of a table (X, Z coords). I hadn't even considered that 2D mode practically eliminates the Z axis and uses X,Y. So the imperfect solution for now is to just rotate your entire map 90 degrees so it's facing the camera. This will be fixed when I get the 2D changes implemented.

    2. This is again due to assuming 3D usage or sprites that turn to face where they're moving towards. I had posted previously how to comment out the lines that do this, but the line numbers have changed since then... I believe it's lines 209, 224, and 313 of Agent.cs now. Again, once I figure out how to make 2D function correctly in the X,Y axes, this won't be necessary.

    Let me know if that does or doesn't do the trick for you, and I'll keep you updated on the 2D progress.
     
    vyshan likes this.
  50. vyshan

    vyshan

    Joined:
    Oct 20, 2018
    Posts:
    4
    Thanks for the quick feedback Schneider!

    The item 2. solved just by commenting on the appointed lines :)
    But the item 1 is still an issue, I don't think it has to do with the Z axis, because I already rotate the camera and map... It looks like every time the game starts, like a Start method or Awake, the 2D sprite moves 1 tile X up and 1 tile Y up, on a diagonal, but that only happens when the game starts, i'm considering to add a "spawn point" to force the sprite to spawn on a specific location, just as a work around. Does that make sense? The strange thing is that the location once moved on a diagonal will keep altered even after resuming the gameplay, like if it is adding += to some X, Y axis