-
Notifications
You must be signed in to change notification settings - Fork 413
Action Node #37
Comments
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 :) |
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... |
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 :) |
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:) |
New feature branch for the UnityFunc: |
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 finally committed my stuff to the UnityFunc feature branch here: 1987f95 |
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. |
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. |
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. :) |
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 :<) |
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? |
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 ? |
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:) Do you know how to set this up in Source tree? 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. |
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. |
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 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:
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; |
You want me to fetch everyone namespace ? Or just the namespace of the class that i passed ? |
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!). 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:( |
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 :
Is that what you want to achieve ? If not i don't understand what you want to do :/ |
The Action Node is seperated into instance calls on objects and static calls on types. It basically has
namespace 1
|_ subnamespace 1
|_ Type 1
|_ Type 2
|_ subnamespace 2
|_ Type 1
namespace 2
|_ subnamespace 1
|_ Type 1
|_ Subtype 1
|_ Type 2
..........
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 :) |
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. |
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:) |
Ok i think i have setup up what you asked. I'm not sure i have done the correct way because :
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 ? NodeEditorWindow.cs, inside the CreateEditor function : NodeEditor.cs, add the following code :
Inside the ActionNode.cs, just to display, add this on the OnGui method (where ever you want) :
Tell me if it's okay for you :) |
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. |
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. |
Ok here are the changes to the initializeAssemblies function, tell me if it's good :
|
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 changed in your code :
And that's all ! All the other things are addition :
And that's it. Tell me what you think. |
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. |
Well if you have a funcation that returns an int or a bool, what you will do ? |
Well I'd just create an output dynamically with that type;) |
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. |
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;) |
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. |
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. |
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. |
Don't think so... |
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 :
|
Oups, seem I forgot to fully account for the new Knob system I implemented. Sorry for that. |
Indeed, i simply had to add this :
and it completly disappear ! |
Ok created the commit: 2d1f070 |
Hi, |
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? |
Indeed but your nodes will be able to be invoked during runtime ? |
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;) |
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. |
Yes, I'll likely develop it further in the future. |
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: |
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. |
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
The text was updated successfully, but these errors were encountered: