I was looking into this and signal callbacks use the RouterEventNode. Gavalakis – Am I just over worrying about things here or is the routereventnode a bit bloated for simple signal callbacks? It hooks up to a lot of unity events some of them being every frame update functions like the animators. I wouldn’t want to introduce all those hooks just to listen to a totally unrelated scriptable object event?
</span>
3.1.0 in 2019.4 builds and has so far no noticeable perfromance issues. Cheers.
Yes I have been working on 3.1.0. For the time being I’m working on moving back to 19.4 since it’s likely the stable option.
I was also unable to build fc in 2020 as it seemed references were also not deserializing properly or something ( the classic no reference static error ) on builds. This I also did not spend much time on figuring out and it could just be something weird I was doing.
Something is quite wrong with the memory either with fc or just straight up unity 2020. Even in sessions where I don’t actually open a graph I will get incrementally longer editor -> play times ( starting at a few seconds ending at 30 ) though this could be due to graph serialization who knows.
Either way excited for future versions of both unity and assets to become stable. Wish me luck with FC in 2019.4 =D
300ms hang in this profiler may not seem like much but it makes it so i cannot use FC basically since when I go to click it won’t register for 300ms and by that time I’ve tried to drag it into a flow slot already to make a connection and by the time it unhangs it now things I want to drag a different node around.
And just to reiterate performance is insanely good in the graphs until the GC starts mucking everything up.
A simple reload of the assembly fixes it up since I presume the issue has something to do with delegates not unsubscribing or something and overtime they build up.
Totally agree! It can be super tedious. In lieu of this you can extend the Blackboard
editor and add your own “Clone last variable” button to help out, or go nuts and rewrite that whole editor to add a copy button.
No worries we’re all busy. I’m using flowcanvas in two different 2018.3 projects and at this point I’m feeling pretty comfy with it’s current prefab pitfalls.
My soultion works just fine ( I’ve made some fixes to it locally since posting though ) except when I deserialize it doesn’t populate object references even though I’m passing it the known object collection and I can’t understand why.
Out of this issue came an actually really handy component. I create a new blackboard component that extends from the vanilla one called “CommonBlackboard”. I put this on my root prefab game object and it holds common variables that exist for all variants but may not have any actual data yet ( as this is the job of the variant to populate with specifics ).
Then the blackboard variables throughout the prefab go look at the common blackboard during editor time ( I create a static MenuItem function that loops through all prefabs and attempts to resolve and then save those assets) using another component CommonBlackboardLoader which lives with the vanilla blackboard.
A bit complicated maybe but it’s been working really well for me. I would say that having something to make blackboards and prefab variants / nested prefabs managable is a must going forward otherwise it breaks a lot of desired workflow. Though you can probably find something more clever than my solution above. The same is true for the actual flow scripts, they are not variant compatible but I think this is less important and just using the asset version instead of bound is fine. It works and doesn’t break the workflow.
And yes it was like that in my actual projects too – it fails to play every other time like clockwork. Very odd.
Anyways if there’s any other information I can provide to help with your 2018.3 update please ask away – I’ve also gotten quite comfy with the new prefab system and PrefabUtility if that info can be of help to you in any way.
Even though I’m an experienced programmer flow canvas has helped me move away from writing lots of specific scripts and instead going with data driven events and I’m pretty happy with it!
( and as a side note if you started a discord server I would hang out and help answer questions )
Update
Today I implemented flow canvas in another existing project and reworked my objects into prefab variants with flow canvas controllers and everything went as expected no errors. So whatever I’m doing with the custom task must just be throwing a wrench in the whole thing.
I went back to the project I submitted earlier and did some more testing. If you unpack the prefab completely it will run, I even filled out some flow scripts and everything was fine.
The moment I set it up as a prefab I start getting errors so I think there’s some issues with the serialization of node canvas I’m triggering somehow but flow canvas does seem to be up and running in 2018.3 =D
I did however notice that the way blackboard variables work ( forgive me if I’m misunderstanding what’s happening ) are not compatible with prefab variant workflows since they’re stored as a single string which explains some of my confusion about data loss there. I might suggest storing them as individual json parts during edit and creating a final serialized string separately to use at runtime. This would be a great addition! In the mean time I’m going to try my hand at extending the blackboard to support this.
I managed to hack it in =P
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
[SerializeField] private List<string> _serializedVariables = new List<string>(); //serialize blackboard variables to json void ISerializationCallbackReceiver.OnBeforeSerialize() { #if UNITY_EDITOR if (JSONSerializer.applicationPlaying) { return; } if (_objectReferences != null && _objectReferences.Count > 0 && _objectReferences.Any(o => o != null)) { hasDeserialized = false; } _objectReferences = new List<UnityEngine.Object>(); _serializedBlackboard = JSONSerializer.Serialize(typeof(BlackboardSource), _blackboard, false, _objectReferences); var data = fsJsonParser.Parse(_serializedBlackboard); var variables = data.AsDictionary["_variables"].AsDictionary; _serializedVariables.Clear(); foreach (var item in variables) { _serializedVariables.Add("\"" + item.Key + "\": " + item.Value); } #endif } //deserialize blackboard variables from json void ISerializationCallbackReceiver.OnAfterDeserialize() { if (hasDeserialized && JSONSerializer.applicationPlaying) { return; } hasDeserialized = true; #if UNITY_EDITOR if (!JSONSerializer.applicationPlaying) { var json = "{\"_variables\":{"; for (int i = 0; i < _serializedVariables.Count; i++) { var item = _serializedVariables<em class="d4pbbc-italic"></em>; json += item; if (i != _serializedVariables.Count - 1) { json += ","; } } json += "}}"; _blackboard = JSONSerializer.Deserialize<BlackboardSource>(json, _objectReferences); } else { _blackboard = JSONSerializer.Deserialize<BlackboardSource>(_serializedBlackboard, _objectReferences); } #else _blackboard = JSONSerializer.Deserialize<BlackboardSource>(_serializedBlackboard, _objectReferences); #endif if (_blackboard == null) _blackboard = new BlackboardSource(); } |
Thanks for the reply and your work on the assets. To start with a few things:
1 – ( see attached image ). Serialization is mismatching types. It says “FlowScriptController” here but the type isn’t actually important, it’s a public field on a custom FSM task with a scene reference attached. The fact that it’s one of your component types as that public field is coincidental – it could be any class.
2 – Blackboard variables do not persist. If I open a prefab, add, remove, or change blackboard variables any prefab instances will not be updated resulting in data loss and other issues. It does work somteimes but will eventually become unusable.
3 – Prefab management is a bit wonky. It always has prefab overrides on the instance with no way to “Revert” or “Apply” ( these both seem to do nothing when working with and paradox components ). I’d recommend testing working with a prefab instance in a scene, opening it in the new prefab editor and making changes, going back to the scene and see how everything reacts. It’s very troublesome.
I’ve attached a project where you can experience all of these things yourself with your source plugins removed. It’s hard exactly to pinpoint more errors as it just all seems to fail everywhere after this point, maybe due to (1) serialization error. Basically anything I do when using a prefab results in a ton of errors I’ll try and get more specific as we go along I apologize if this comes off a bit vague.
– Open project
– Import node / flow canvas from asset store ( I put them in Plugins folder – it would probably be best for me to just email you a full project privately )
– Press Play or otherwise try and do any development.
Attached project: ( forums would not let me upload ) https://drive.google.com/file/d/1m6nAsMguFeSvfZar2MSNtSBd8pgzXySb/view?usp=sharing
Sure there’s quite a bit so I’ll need some time to prepare. Is there a good email address for sending projects or should I just upload publicly and remove the paid flow/node source?
Events can be cool but this seems like a bit weird time for events. At the very simplest translation you can do exactly your code version in flow canvas. Expanding on this I like to build kind of “Controller” classes that handle code for me but I *assemble* them in flow canvas. This gives me powerful control of my code in my controllers while giving me the excellent visual design logic. So I might I have [OnInput] => [Self.MyComponent.Shoot()] instead of building longer flow trees.
Example of code translation below.
Edit:
It occurs to me that you’re not wanting to invoke a function as per your code but execute additional flow controller logic. In this case events or a custom function does make sense!