Seneral / Node_Editor_Framework

A flexible and modular Node Editor Framework for creating node based displays and editors in Unity
https://nodeeditor.seneral.dev
MIT License
2.01k stars 414 forks source link

Multiple trees node calculation #69

Closed koniu699 closed 8 years ago

koniu699 commented 8 years ago

Hi, I've encountered a problem with Node Editor. I'm using it to create skill trees. Each node in skill tree is a individual skill, and it can have parent skill (only one) and child skills (multiple). Each time I create a skill tree I store child nodes in a easy accessible List, and I do this in Calculate method. In project I wish to have multiple skill trees. It is easily done by creating multiple canvases. Here is sample tree I've created (other 2 trees are similar looking): screen

I've created a class SkillTreeNode deriving from Node class that framework provides. In SkillTreeNode I've got a List<SkillTreeNode> childNodes in which I store all child nodes from Output. Everything works as charm to that moment. All references are set and it's looking like ready to go.

I've created a class, which I use in runtime, that references all of my skill trees. It's job is to check if a skill is available for player on certain level and if that skill can be used. It uses the childNodes to do this.

But when I do foreach o every element of childNodes, Unity says that there is some elements and every element is null. It is true for all skill trees but the one that was processed (Calculate was called) last.

For example if I got 3 skill trees: 1,2 and 3. If I process skill tree 1, childNodes for every element in that tree will be set properly and there won't be any nulls. But in skill tree 2 and 3 all childNodes will be nulls. If I process skill tree 3, childNodes in that tree will be setup properly, but for trees 1 and 2 they won't.

I'm not sure if it is my fault or something is wrong in framework.

Here's my Calculate method:

public override bool Calculate ()
        {
            Debug.Log("Calculate call on: " + this.skillName);
            childSkills.Clear();
            parentSkill = null;
            if (Inputs[0].connection != null)
            {
                parentSkill = (SkillTreeNode)Inputs[0].connection.body;
                isRootNode = false;
            }

                foreach (var node in Outputs[0].connections)
                {
                    Debug.Log(SkillName + " " + ((SkillTreeNode)node.body).SkillName);
                    childSkills.Add((SkillTreeNode)node.body);
                }
            return true;
        } 

Thanks for any help

Seneral commented 8 years ago

It's probably because of the saving system. I really have to write something up for the documentation on this topic. It most probably happens because your references get lost when the save system clones and replaces the nodes. There is an interface consisiting of two methods in Node.cs that would be able to fix this, but first off, you may be able to avoid that all together! So in the childNodes list, you store every connected node. Why not just access the connected inputs from the output directly? You could also make this a property accessing the output connections instead for simplicity... For example: Outputs[0].connections So you don't need to take care of updating this list.

Also, pro tip: If you want the tree to be top->bottom, you can change the orientation of each knob in the Node constructor by a simple overloaded knob constructor;)

koniu699 commented 8 years ago

I've overcome the problem using similar solution You provided :P I simply get all nodes directly from Outputs[0].connections Still in my opinion it's a bit counter intuitive to write that method, since in framework You can calculate the values every time you do something in the tree.

Thanks for the pro tip :D I was going to do that in first iteration, yet it took me some time to fix my issue, so I will probably make the change next iteration.

Seneral commented 8 years ago

So, has this been resolved for you? Sorry for not checking in for so long...

koniu699 commented 8 years ago

As I said, I access all connections of each node and then store references gathered from there. It's a simple fix and it works fine.