Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Action Node #37

Open
Seneral opened this issue Feb 18, 2016 · 50 comments
Open

Action Node #37

Seneral opened this issue Feb 18, 2016 · 50 comments

Comments

@Seneral
Copy link
Owner

Seneral commented Feb 18, 2016

Description: A generic node for calling actions, both static and instance. The Inputs and Outputs should adapt automatically.

Progress: Currently put on hold because we are unable to just serialize a function. I'm adressing this with a UnityFunc, which is serializeable and also needed for the StateMachine. Kamigaku on the forums has a specialised version already running afaik:)

Location: Due to the dependecny on UnityFunc, mostlyUnityFunc.cs and UnityFuncEditor.cs

WIP Branch

@Kamigaku
Copy link

Currently my version is not "running" entierly. I need one or two fixes plus a major update regarding the fact to right now you can only point to a constant class. But it will be (i think), pretty easly done (i hope :)). I can for the moment serialize everything and save it as a JSON or as an asset to modify it later. I think i will also wait a bit to give it to you because there is a lot of improvements to do and cleaning the code. I'd like to have a definitive push and you saying me too adapt my current work with yours so i'll be sure that what i'm doing is fitting the current version. Meanwhile, i'll keep working on it, i keep saying that it should be over soon, but i honestly think it's true. I will have a lot of free time next week, so i'll hope it will be over by the next week :)

@Seneral
Copy link
Owner Author

Seneral commented Feb 19, 2016

Cool, I hope to get this done without a seperate JSON serializer though... I think we should just focus on the other model of the serialized UnityFunc that I'm currently working on, because it is a better aproach from the ground up I suppose...
We will be able to work on this better using this Git Flow models (#47) ;)

@Kamigaku
Copy link

That would be good to use the branches yes ! So that if you do a push on a develop branch i'll be able to pick it, work on it. I'll wait for your new UnityFunc :)
We indeed need some workaround to see the progression of it because right now we are just waiting a push to help you on the work ^^

@Seneral
Copy link
Owner Author

Seneral commented Feb 19, 2016

I'm very sorry for this but I feel unconfortable pushing code that is not fully functional :/ Also we then might work on the same stuff, which I would like to avoid;) Anyway, I try to create a branch for that and to push my WIP code to it:)

@Seneral
Copy link
Owner Author

Seneral commented Feb 19, 2016

New feature branch for the UnityFunc:
https://github.com/Baste-RainGames/Node_Editor/tree/feature/WIP_UnityFunc
Will be used for this feature from now on:)

@Seneral
Copy link
Owner Author

Seneral commented Feb 19, 2016

It's simply stupid bug is preventing me from pushing. It's actually the Unity Serialization system that causes this (as always it comes down to that piece of s***). In UnityFunc I was expected to either have a field (of a class type) to be uninitialized (null) or properly initialized. Well, it turns out the serialization system has assigned it a default value that is completely useless and broke my system. Guess how long that took me to figure out what was actually going on !!
I'm trying to find a workaround. Until then I have to delay a push again, sorry:(

@Seneral
Copy link
Owner Author

Seneral commented Feb 19, 2016

I finally committed my stuff to the UnityFunc feature branch here: 1987f95
Is that how it's going to work? :)

@Seneral
Copy link
Owner Author

Seneral commented Feb 19, 2016

Future plans are (besides making ActionNode functional) to section the commands to derived and direct members and to remove sub functions from primitive types (f.E. no int32.GetType() / int32.ToString ()), if you agree, etc.

@Kamigaku
Copy link

I have read what you are doing and it's seems pretty well advanced. I have done some testing and i think there is an issue with the object that you pass. For example if i pass a script, i got the MonoScript method and not the type that i define in my script.
Regarding the GameObjects it seems to be good but i think we need to fetch each component, adding an entry in the menu for each Component and display the functions available.
Before moving any further i think we should try to do that and i'm pretty sure fixing that issue will fix the thing that you mentionned before by simply adding a BindingFlags.DeclaredOnly in the Command building.
What do you think ?
But anyway, good job, that's pretty sick what's done :)

@Seneral
Copy link
Owner Author

Seneral commented Feb 20, 2016

Yep, I'm now adding a bit more structure to the GenericMenu. For example, a base submenu for base methods, type specific stuff like a submenu to access the type the monoscript representates instead of the object, and components for a gameobject, etc. :)

@Kamigaku
Copy link

Hi,

I have done some tests regarding an object pointing to a MonoScript, if you take the ActionNode class and in the GuiButton pick a function you do this :

if (startFunc.TargetObject.GetType() == typeof(UnityEditor.MonoScript)) 
{
    functionSelectionMenu = FunctionSelector.BuildCommandExecutionSelection(((UnityEditor.MonoScript)startFunc.TargetObject).GetClass(), BindingFlags.Static | BindingFlags.Public,  TransformSelectedFunction, 3);
}
else 
{
    functionSelectionMenu = FunctionSelector.BuildCommandExecutionSelection(startFunc.TargetType, BindingFlags.DeclaredOnly | BindingFlags.Static, TransformSelectedFunction, 3);
}

It pops out only the function of the scripts. I think i changed to bindings for the other one (they were not like that in your code :<)
I think i'll go and do another case for the GameObject but tell me if that is good for you.

@Seneral
Copy link
Owner Author

Seneral commented Feb 20, 2016

Yes this seems good, I did not work on this today either (yet). But I plan to do some other restructures, too (mentioned above). Can we coordinate so we do not do conflicting/duplicate work?

@Kamigaku
Copy link

I don't know in which country you live and what are your work times. Just to tell you, i'm in vacation for a week so i'll be able to work pretty much when i want. I plan to work every morning on the library to make it evolve but i don't know how we can split the work. You have pretty much all the knowledge on it. For example, what do i do with the modification i did today ? Should i push them ? You take them and add it to the code ?
I'll plan maybe on work on it tonight (it's 20:53 here) to implement the GameObjects. So tell me, what do you want me to do and how can we assure that what i do you can use it ?

@Seneral
Copy link
Owner Author

Seneral commented Feb 20, 2016

Hey, we're actually in the same timezone;) My work times are.... whenever I want. I have to go to school but in my freetime I generally work whenever I can:)
Anyway, you're right with what you're saying - it may be best that we make use of the feature branch (https://github.com/Baste-RainGames/Node_Editor/tree/feature/WIP_UnityFunc)

Do you know how to set this up in Source tree?
If not, go first enable Git Flow at the top right, following the instructions there. Then you can select any branch you want to work on by right-clicking it under the remote foldout (you may need to right click origin -> fetch from origin to update it first) and selecting checkout. Then it will automatically compare with the selected branch, targets all commits to this branch, etc.

Then we have to etablish a pull request workflow so that we can review it first and the other has to integrate it manually for his feature to merge correctly when he wants to create a pull request.

Regarding work splitup, I think it's best to exactly categorize what we do.
For example, you could create a type GenericMenu dropdown (similar to that in FunctionSelector) so in the first level there's the assembly, in the second the types, in the third the subtypes of that type, etc. This will be used for the static function selector. Do you want to do that?
Problem is, the stuff with GameObject components might conflict with the restructure which I plan to do. What do you say?

@Kamigaku
Copy link

I have some difficulty understanding how those git/bit bucket, etc... work but i think i have done what is needed (see this http://i.imgur.com/tn25i3M.png ). We are starting to use it at school and if i remember correctly we were asked to create our own branch, develop on it and then someone will merge everything so that all the work is combined, maybe is what you want to do ? Do i need any right to do that ? I'm kinda new to this domain because i usually work alone on a project and never seen the utility of this kind of tools.
Concerning your request, if i understand correctly you ask me to do something like a tree search on a class to find all the parents and all the child and display the methods accordingly to their position in the tree ?

@Seneral
Copy link
Owner Author

Seneral commented Feb 20, 2016

Yep, seems about right. Under branches you've selected the WIP_UnityFunc branch so It'S all setup. To be honest, I've first worked with GitHub when Baste first introduced me and created the Repo. And I was just gotten recently familar with the Git Flow stuff when pmhpereira made me aware of it in #47. Before I too did only work alone.
Regarding the workflow, seems like you're doing it slightly different in school, whichis not bad, but it's best that each individual dev implements his feature in a seperate branch and, after receiving feedback (through pul requests or something like that), he rebases his branch (basically manually implements it with each commit that has been comitted to the master branch since he first forked it), and then he can push his feature without conflicts into the master branch.
This rebasing and merging process could be done by one person indeed, but I really wouldn't want to be this person lol :D

Regarding the type picker, it's like a way to select any type to call static functions on. To make this convenient this sctructure would be great:

namespace 1
    |_Type 1
    |_Type 2
        |_SubType1
    |_Type 3
namespace 2
    |_Type 1
    |_Type 2
....

Hope you understand. This has to be done at some point and as this should not conflict with what I do this would indeed be great if you could do that:) Currently, I only do the static function check with a text field:

if (startFunc.TargetObject == null)
{ // TODO: Type dropdown
    string typeNameEdited = GUILayout.TextField (typeName);
    if (typeName != typeNameEdited) 
    { // Input was changed, check if the input is a valid type
        typeName = typeNameEdited;
        Type type = Type.GetType (typeName);
        if (type != null) 
        { // Assign new type
            startFunc.ReassignTargetType (type);
            functionSelectionMenu = null;
        }
    }
}
else
    typeName = startFunc.TargetType.Name;

@Kamigaku
Copy link

You want me to fetch everyone namespace ? Or just the namespace of the class that i passed ?

@Seneral
Copy link
Owner Author

Seneral commented Feb 21, 2016

I think it's best not to fetch the type when a Monoscript was passed. It's better to have a static type selector instead when no object is added (which we're talking about). This is cleaner and also enables to adress types that doesn't have it's own script (MonoScript proposely has only one type declared). This also enables for targetting types in other namespaces, types you do not have the source from and subtypes of a type.

There are so many possible types and namespaces a user could adress! For example anything in the system namespace (System.IO.File, ...), the custom script assemblies, Unity assemblies, etc. That is just too much because we would need to fetch EVERY type in those assemblies when creating the GenericMenu (well over a thousand types!).
So I think we can limit the selection on UnityEditor (if in editor), UnityEngine, and all custom script assemblies (unityscript firstpass, c# firstpass, unityscript editor, c# editor, ...). If you want to adress something else, you just need to create such a function in any of your scripts. Also, remember sub-assemblies (I forgot them in the example above) ;)

There's even more improvement possible on the GenericMenu side, in order to change this. OnDemand menu building would come first into my mind, which is also useful for the function selector (unlimited menu depth, faster start up, etc.). I think I'll consider that. Then we'll loose the same API as the Editor GenericMenu, though:(

@Kamigaku
Copy link

What i don't understand is where do you want me to do that and why. We are basing the Action Node on the fact that you have to put an Object inside the Object field and then we will recursivly (is that a word ? :x) fetch fonctions or static field to display. So if for example i have an Entity script extending AEntity that have some static field it will display like that :

   GameObject
      |_ Sub fields and method of GameObject
      |_ AEntity
          |_ Sub fields of GameObject
          |_ Entity

Is that what you want to achieve ? If not i don't understand what you want to do :/

@Seneral
Copy link
Owner Author

Seneral commented Feb 21, 2016

The Action Node is seperated into instance calls on objects and static calls on types. It basically has

  1. An object field. This takes a target object to call functions on.
  2. A type dropdown [IF target object == null] to select the target type to call static functions on:
namespace 1
    |_ subnamespace 1 
        |_ Type 1
        |_ Type 2
    |_ subnamespace 2
        |_ Type 1
namespace 2
    |_ subnamespace 1 
        |_ Type 1
            |_ Subtype 1
        |_ Type 2
..........
  1. A function picker. If the targetObject is specified, shows all the instance functions to call on the object. If no targetObject is specified but the targetType, it shows all the static function to call on that type.
    Example Layout of both:
base [Type] // baseType of targetType
    |_ [ReturnType] function([Parameter]) // called on parent baseType
         |_ [ReturnType] function([Parameter]) // called on parent returnType
         |_ [fieldType] variable // called  on parent returnType
    |_ [fieldType] variable // called on baseType
         |_ [ReturnType] function([Parameter]) // called on parent returnType
         |_ [fieldType] variable // called  on parent returnType
|_ [ReturnType] function([Parameter]) // called  on targetType
    |_ [ReturnType] function([Parameter]) // called on parent returnType
        |_ [fieldType] variable // called on parent returnType
|_ [fieldType] variable // called on targetType
    |_ [ReturnType] function([Parameter]) // called on parent returnType
    |_ [fieldType] variable // called on parent returnType
..........

Hope that makes it better to understand :)

@Kamigaku
Copy link

Ok i think i get it, i didn't know what was the use of the text field on right i tought it was something that you forgot to remove. So it's a text field for the moment that let you pick a Type and call only static function on it.
You want me to fetch all the types available (not all of them), display them on dropdown and when a type is picked display all the functions available for that types and is ascending and descending types.

@Seneral
Copy link
Owner Author

Seneral commented Feb 21, 2016

When a type is selected, just set it as the targetType just as the text field does for now:) But yes, that's basically what you could do if you want:)

@Kamigaku
Copy link

Ok i think i have setup up what you asked. I'm not sure i have done the correct way because :

  • I load it only once, it's pretty long (not that long but we can't afford to load it every time an ActionNode is created)
  • I don't use your BuildCommand class, maybe i can but i haven't checked how you use it.

Basicly when the NodeEditor is loaded in preload all the static functions from all the Assemblies of the CurrentDomain. It does a very nice work and all the static functions are shown. Is that what you needed ?
Right now i don't know if i should push my code or send it to you so... Here are the modifications :


NodeEditorWindow.cs, inside the CreateEditor function :
NodeEditor.initializeAssemblies();


NodeEditor.cs, add the following code :


public static UnityEditor.GenericMenu assembliesMenu = new UnityEditor.GenericMenu();
        /// <summary>
        /// Initiliaze all the assemblies once at editor opening
        /// </summary>
        public static void initializeAssemblies() { 
            Assembly[] allAssemblies = AppDomain.CurrentDomain.GetAssemblies();
            for(int i = 0; i < allAssemblies.Length; i++) {
                foreach(Type type in allAssemblies[i].GetTypes()) {
                    if (type.Namespace != null) {
                        MethodInfo[] allStaticMethods = type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
                        for (int j = 0; j < allStaticMethods.Length; j++) {
                            assembliesMenu.AddItem(new GUIContent(type.Namespace.Replace('.', '/') + "/" + type.Name + "/" + allStaticMethods[j].Name), true, SelectedAssembly, allStaticMethods[j]);
                        }
                    }
                }
            }
            Debug.Log("Done loading assemblies");
        }

        private static void SelectedAssembly(object methodInfo) {
            MethodInfo methodToCall = methodInfo as MethodInfo;
            Debug.Log("I will call " + methodToCall.Name);
        }

Inside the ActionNode.cs, just to display, add this on the OnGui method (where ever you want) :

GUILayout.BeginHorizontal();
        if(GUILayout.Button("Pick Assembly")) {
            NodeEditor.assembliesMenu.ShowAsContext();
        }
        GUILayout.EndHorizontal();

Tell me if it's okay for you :)

@Seneral
Copy link
Owner Author

Seneral commented Feb 21, 2016

You're fetching each static method from the types, do you? This will be done in the function picker after the type is selected. It'S really only a type we're interested in here.
But don't scrap it completely. When iterating through each type, don't check if the namespace is empty, but instead call ToString on the type which will get the fully qualified name (MyNamespace.MyType for example). Do as you already did and replace the dots with slashes. Then add the types (not the static methods, as you do now).
Additionally, you have to iterate over the nested types, or subtypes (GetNestedTypes) and display them in a group next to the main type. And please also filter the assemblies, right now you're iterating over EVERY assembly (horrible many!). Filter to all assemblies beginning with 'Unity' or 'Script'. That should work:)

@Kamigaku
Copy link

Ok, i have modificated it a bit. I still have issue with the NestedTypes, there are some strange classes. I'll do the filter tomorrow, getting a bit tired. I'm not posting the code because the changes are minimum.

@Kamigaku
Copy link

Ok here are the changes to the initializeAssemblies function, tell me if it's good :

        /// <summary>
        /// Initiliaze all the assemblies once at editor opening
        /// </summary>
        public static void initializeAssemblies() { 
            Assembly[] allAssemblies = AppDomain.CurrentDomain.GetAssemblies();
            for(int i = 0; i < allAssemblies.Length; i++) {
                foreach(Type type in allAssemblies[i].GetTypes().Where(type => type.ToString().Contains("Unity") || type.ToString().Contains("Script"))) {
                    foreach(Type nestedType in type.GetNestedTypes()) {
                        assembliesMenu.AddItem(new GUIContent(type.ToString().Replace('.', '/') + "/" + nestedType.Name), true, SelectedAssembly, nestedType);
                    }
                    assembliesMenu.AddItem(new GUIContent(type.ToString().Replace('.', '/')), true, SelectedAssembly, type);
                }
            }
            Debug.Log("Done loading assemblies");
        }

@Seneral
Copy link
Owner Author

Seneral commented Feb 22, 2016

Ok I still modified it a bit to cache the type stuff.
First, I had some problems, like this mess:
screenshot14
I changed some things so it is very structured now, but it took me some time. Result:
screenshot16
I will create a pull request tomorrow, now I need sleep;)

Also noticed the custom GenericMenu needs some work. Desperatively.
To name a few things, when it's called from inside group, it behaves weird in conjunction with GUI Scaling, and when list get's huge it silently clips outside of the border without a way to access the upper ones, and positioning is also suboptimal.
Additionally, some extra features that the editor one does not have could be added, too, including on demand menu building, improved API, combined items and groups (item can be further expanded, rather than having the item and the group seperately), etc.
A lot to do that I'll be working on;)
That shouldn't pause developement on this one, though. For now we should simply using the editor generic menu for this.

@Kamigaku
Copy link

Hi,

Since i have nothing else to do and you finised the Assembly fetcher, i keep working on the previous node that i had start. I pretty much reorganised everything to make less modification on your base code and it worked pretty well. I have the possibility to save, the possibility to fetch a given object and displaying all his static functions. Maybe it will step on your toes but i wanted to finish it. I'll link you the .zip of my project containing a base unity project and a test script (IAMethods).
What i need to finish is the JSON export but basicly all i need is over (i think :))

What i changed in your code :

  • Node.cs : the outputs creation return output created, which seems... obvious ! In the InitBase, i check if the node created is a FunctionNode and if he is the first one of his kind. If yes i also create two nodes : Begin and End that will help determine where the logic start and end.
  • NodeInput.cs : i have just changed the CanApplyConnection. But what i did is not good. We need a NodeInput-like that doesn't rely on the types to be connected.
  • RTEditorGUI : added some functions that doesn't impact the older ones.

And that's all ! All the other things are addition :

  • BeginNode, EndNode & FunctionNode are new nodes.
  • Function, FunctionParameter & FunctionResponse help me split the logic.

And that's it. Tell me what you think.

NodeEditorTestProject.zip

@Seneral
Copy link
Owner Author

Seneral commented Feb 23, 2016

I didn't yet understood the concept of the node fully, for example why those multiple results? I think the Start and End node are just to structure everything - fine.
I'm sorry that I somehow 'took over' the job (remember at the beginning you wanted to start the ActionNode), but I already had such a model in my imagination that would (possibly) be perfectly generic and I somehow failed to share this idea. So I basically developed it alongside you which was not optimal but hey, why notxD
Anyway, back to work;)

@Kamigaku
Copy link

Well if you have a funcation that returns an int or a bool, what you will do ?
My concept was to use the nodes an AI question, it will call a function and depending on the answer, will go here or there. That's what i wanted to do with the results. Predict possible answers and draw the road to the next Node, etc...
I'm waiting to see what will you propose me because i think this will be interesting !

@Seneral
Copy link
Owner Author

Seneral commented Feb 23, 2016

Well I'd just create an output dynamically with that type;)
This is what I'm currently doing to the Action Node, so it actually works for the first time;)

@Kamigaku
Copy link

Ok but there a multiple amont of possible answers... Creating one output to say that function is connected to this one without saying WHY it goes here.
But i think i'll just wait to see what you will cook us !

@Seneral
Copy link
Owner Author

Seneral commented Feb 23, 2016

Well the action node will represent an element in the calculation chain of the calculation system. Everything 'around it' is handled by that system, so we can simplify the purpose of the action node as follows: select a function, and specify targetObject, parameters, etc. as inputs and return type and ref/out parameters as outputs. This can then be used anywhere to call functions and retrieve their values, we don't have to worry avout the interconnections of the nodes around it, the calculation system will handle that;)
If you meant something else, tell me;)

@Kamigaku
Copy link

Can you give me an example of use of your ActionNode ? Maybe i'm misunderstanding what you want to do. Like a case that your node will fill.

@Seneral
Copy link
Owner Author

Seneral commented Feb 23, 2016

Well, this whole framework does not serve a specific purpose as of now, so it's hard to give a concrete example. Basically any use case where you might want to call an external function.
You need a functionality in the node system that none of the nodes provide, and you don't want to write a custom node for each case? Call an external function, even built-in ones.
You could fetch all objects in the current scene using an external function. You could easily use external libraries you want to test out without putting much work into integrating it into the system with custom nodes. Etc.
From the examples above it might seem to slightly drift into visual scripting systems, but that's not actually the case.

@Kamigaku
Copy link

So if i understand you are interpretating the answer the function is giving you, you are just passing it or returning it to the caller. You don't have the paths possibility ? As you said, you want to do visual scripting, do this, then this, then this but not do this, if this is true do that and if that is false do this because you are intrepreting the answer in the function that you will call.
So we are doing two differents right ?

@Seneral
Copy link
Owner Author

Seneral commented Feb 24, 2016

Don't think so...
First, I meant to say it may look like visual scripting from the examples above, but it can be used anywhere.
I think the differences with our implementation is that you can directly evaluate the return type of the function and then take apropriate following actions, right? This is good for an AI, but in my opinion too specific. With my implementation you indeed have to evaluate the result in a following action node explicitly.
So your node has several advantages in some use cases, and I think now that I understood it you should can use it pretty well:)
But still think your fetching method has some disadvantages. And the result evaluation could be done with transitions when they're done;)

@Kamigaku
Copy link

Then i'll wait for all the bigger updates but right now i need something to work with and i'm satisfied with what i have :)

Just a question, i have an issue with the render. In the previous version when i deleted dynamicly an output the Knob would disappear with it but with the new version it doesn't work. The output is deleted but the output is still rendered. Am i deleting the output correctly :

if (this.responses[toDelete].output.connections.Count > 0) {
    for (int j = 0; j < this.responses[toDelete].output.connections.Count; j++) {
        this.responses[toDelete].output.connections[j].RemoveConnection();
     }
}
concernedNode.Outputs.Remove(this.responses[toDelete].output);
this.responses.RemoveAt(toDelete);

@Seneral
Copy link
Owner Author

Seneral commented Feb 24, 2016

Oups, seem I forgot to fully account for the new Knob system I implemented. Sorry for that.
You know, I've generalized the NodeKnobs and stored them in a nodeKnob list in the node that is drawn on, not just the inputs/Outputs list (which are still existant though). Inputs/Outputs is only there to ease reference to the knobs, drawing is performed on nodeKnobs. Seem I forgot to remove the knobs from the NodeKnob array though:(

@Kamigaku
Copy link

Indeed, i simply had to add this :

concernedNode.nodeKnobs.Remove(this.responses[toDelete].output);

and it completly disappear !

@Seneral
Copy link
Owner Author

Seneral commented Feb 28, 2016

Working on... stuff:
screenshot2
:D
I've an ExpressionNode (aswell as ConversionNode) setup to quickly input and convert any type for the action node (along with added support for arbitrary connection types, color generation for each type is on the TODO list;) ).
Action Node aswell as UnityFunc is alot more fleshed out now, UnityFunc now supports methods, properties and fields, etc. You can chain commands one after another, aslong as they are implicit (no parameters), that means you don't have to chain lots and lots of ActionNodes one after another to work on the result of the previous one.
I'm exited about all this and hope that I can create a pull request (or commit if I cannot manage to create a pull request lol) tomorrow:)
There are still alot of rough edges and even errors, so I'll continue to polish it.

@Seneral
Copy link
Owner Author

Seneral commented Feb 28, 2016

Ok created the commit: 2d1f070
There is a problem with the action node throwing ArgumentException: method return type is incompatible which seems to be related to mono (see)
If I find no other solution I'll use the answer of the link above which unfortunately is alot slower than create delegate:( This also did work at some cases.
Additionally, I did not test the instance commands of the action node (targetObject specified) yet:(
But I seriously have to sleep now.

@Kamigaku
Copy link

Hi,
I'll take it and try it ! On my side i have finished it pretty much completly... I'm able to create my nodes and call my functions during runtime with a JSON file generated by the Node Editor but... now that i have it, i don't see the use of it !
It was a wrong idea to use it has an IA creator but maybe i'll find an idea to use it !

@Seneral
Copy link
Owner Author

Seneral commented Mar 1, 2016

I think one point is that you create the functions to call in a separate script. Then why not create a new node for that case directly?
I think one benefit of such an action node is that you can quickly call any function, alot of them, without additional scripting. And that's about what I did in the action node implemetation.
But I see your point, for an AI system it might be simply better to create unique nodes for each function/feature/whatever...

@Kamigaku
Copy link

Kamigaku commented Mar 2, 2016

Indeed but your nodes will be able to be invoked during runtime ?

@Seneral
Copy link
Owner Author

Seneral commented Mar 2, 2016

Yep they will, except the platforms where reflection is not supported of course (iOS). Also only when I'll be able to fix the error that is currently thrown;)

@Roni1993
Copy link

Roni1993 commented Sep 5, 2016

are there any intentions to follow up on this Issue?

since i'm currently trying to do a similar Addtion to the Node_Editor. Basically i want to use the node-editor to view my Events and all the Observer for each event and for this i could actually build upon what you´ve created sofar. Though this system would gain quite some size.

@Seneral
Copy link
Owner Author

Seneral commented Sep 6, 2016

Yes, I'll likely develop it further in the future.
But I have by now developed a better replacement for UnityFunc, which does need a little bit of work to function with return- and parameter values but is way more powerful. It can serialize basically anything, any target object (Unity- or System object), method (normal, static, generic typed or anonymous with context), etc.
So if that's what you're interested in, you might want to check out this forum post.
Can't fully get wat you're looking for though, do you want to call events? Or receive them from outside`? If you can explain in more detail, I'll be able to help you further:)

@Roni1993
Copy link

Roni1993 commented Sep 6, 2016

i guess its kinda hard to describe but i´ll try my best.

basically right now i have built a small "framework" that builds on two central ideas. the first idea is that almost all components are just connected via Events which are sent by broadcasters and then the observers just fetch this event and then process it. those maybe also send more events or just enable some interaction or save data.

the second idea is that my game uses a central statemachine that controls major transitions in the gamestate. those changes in state will then also be bordcasted as event and every observer can then decide what to do based on this event.

what i want to achive with the Node-Editor is to create a dynamicly created overview of all broadcasters and observers and the Statemachine. this would would allow a developer get a good overview of the whole system with just one glance at the Canvas.

so basically i need to create some "dynamic manager" that takes care of all those events and also i need to think of a smart way manage those Events.

regarding your serializable Actions i'm not quite sure sofar if i'd really need them but my overview over the Framework of the Node_Editor is quite sparse.

Edit:
just took a look at the Serializable Actions i think they might come in handy but i still need to figure out the best way to implement those features into the Node Editor

@Seneral
Copy link
Owner Author

Seneral commented Sep 6, 2016

Well then you can use UnityEvents (they are serialized) but they are quite limiting if you want to use them for a complete events system.
Are those connections/events specified in the editor or at runtime?
If you do need to serialize them manually, my serializable Action might be useful for you:)
Also, the new diagram on #46 might give you a decent overview over the framework structure (need feedback for it) ;)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants