NodeCanvas Forums › Support › Refactoring BTs
(I hope you don’t mind me spamming the forums with all my requests..)
I would like to automatically refactor some content in my BTs, e.g. replacing one node for another, copying some values from one parameter to the other, changing parameters, replacing one task for another, etc.
I was thinking it would probably be possible to add a bit of code that modifies the BehaviourTree just after it has been deserialized and then use AssetDatabase.ForceReserializeAssets to trigger load+save for the assets that reference/contain that BT. (or maybe even refresh all assets)
Do you think this approach could work? Where could I hook up my code that will modify the loaded BehaviourTree?
Thanks!
Hey,
Not a problem 🙂
Hmm. This could be possible. There can be many ways to go about this, but I could add a static event Graph.onAfterGraphDeserialized
in which you could hook up some code to modify it after the fact. Would that be something that would work for you?
Thanks 🙂
Join us on Discord: https://discord.gg/97q2Rjh
Could you elaborate a bit more? E.g. how would I get a reference to the Graph that was deserialized? Thanks!
Hey,
It will be a static event where the Graph reference will be passed as the argument.
public static event System.Action<Graph> onGraphDeserialized;
As such you will be able to do something like this:
1 2 3 4 5 6 7 8 9 |
void OnEnable(){ Graph.onGraphDeserialized += OnGraphDeserialized; } void OnGraphDeserialized(Graph graph){ //... } |
Let me know.
Thanks.
Join us on Discord: https://discord.gg/97q2Rjh
I see. That sounds useful, thanks.
Hi Gavalakis,
I’ve upgraded our project to Unity 2018.3.0f2, and I was trying out AssetDatabase.ForceReserializeAssets();
to see how that would affect the serialized data of NodeCanvas. It looks like most of the data is deserialized and then serialized to the current version, but there are exceptions. Some Scenes have PrefabInstances and the data in the scene file shows old version serialized data under the m_Modifications of “propertyPath: boundGraphSerialization”. Will this affect anything? Is this stale data?
Speaking of ‘boundGraphSerialization, I remembered we talked about it in this thread: https://nodecanvas.paradoxnotion.com/forums/topic/some-questions-and-requests-regarding-serialization/
I tried an unconditional boundGraphInstance.hideFlags = HideFlags.HideAndDontSave;
and ran another ForceReserializeAssets. In the scene files, the duplicate data was removed as expected (though the PrefabInstance m_Modifications data as discussed above remains). All seems to be working fine, but I did get a bunch of errors during/after the force reserialization:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
ArgumentException: Object type UnityEngine.Object cannot be converted to target type: UnityEngine.Transform Parameter name: val System.Reflection.MonoField.SetValue (System.Object obj, System.Object val, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoField.cs:148) System.Reflection.FieldInfo.SetValue (System.Object obj, System.Object value) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/FieldInfo.cs:150) ParadoxNotion.Serialization.FullSerializer.Internal.fsMetaProperty.Write (System.Object context, System.Object value) (at Assets/ParadoxNotion/CanvasCore/Common/Runtime/Serialization/Full Serializer/Reflection/fsMetaProperty.cs:117) ParadoxNotion.Serialization.FullSerializer.Internal.fsReflectedConverter.TryDeserialize (ParadoxNotion.Serialization.FullSerializer.fsData data, System.Object& instance, System.Type storageType) (at Assets/ParadoxNotion/CanvasCore/Common/Runtime/Serialization/Full Serializer/Converters/fsReflectedConverter.cs:102) ParadoxNotion.Serialization.FullSerializer.fsSerializer.InternalDeserialize_5_Converter (System.Type overrideConverterType, ParadoxNotion.Serialization.FullSerializer.fsData data, System.Type resultType, System.Object& result) (at Assets/ParadoxNotion/CanvasCore/Common/Runtime/Serialization/Full Serializer/fsSerializer.cs:886) ParadoxNotion.Serialization.FullSerializer.fsSerializer.InternalDeserialize_4_Cycles (System.Type overrideConverterType, ParadoxNotion.Serialization.FullSerializer.fsData data, System.Type resultType, System.Object& result) (at Assets/ParadoxNotion/CanvasCore/Common/Runtime/Serialization/Full Serializer/fsSerializer.cs:878) ParadoxNotion.Serialization.FullSerializer.fsSerializer.InternalDeserialize_3_Inheritance (System.Type overrideConverterType, ParadoxNotion.Serialization.FullSerializer.fsData data, System.Type storageType, System.Object& result, System.Collections.Generic.List 1& processors) (at Assets/ParadoxNotion/CanvasCore/Common/Runtime/Serialization/Full Serializer/fsSerializer.cs:857) ParadoxNotion.Serialization.FullSerializer.fsSerializer.InternalDeserialize_1_CycleReference (System.Type overrideConverterType, ParadoxNotion.Serialization.FullSerializer.fsData data, System.Type storageType, System.Object& result, System.Collections.Generic.List 1& processors) (at Assets/ParadoxNotion/CanvasCore/Common/Runtime/Serialization/Full Serializer/fsSerializer.cs:743) ParadoxNotion.Serialization.FullSerializer.fsSerializer.TryDeserialize (ParadoxNotion.Serialization.FullSerializer.fsData data, System.Type storageType, System.Type overrideConverterType, System.Object& result) (at Assets/ParadoxNotion/CanvasCore/Common/Runtime/Serialization/Full Serializer/fsSerializer.cs:705) UnityEngine.Logger:LogException(Exception) ParadoxNotion.Services.Logger:ForwardToUnity(LogType, Object, String, Object) (at Assets/ParadoxNotion/CanvasCore/Common/Runtime/Services/Logger.cs:100) ParadoxNotion.Services.<Internal_Log>c__AnonStorey0:<>m__0() (at Assets/ParadoxNotion/CanvasCore/Common/Runtime/Services/Logger.cs:88) UnityEditor.EditorApplication:Internal_CallDelayFunctions() |
Hi Gavalakis,
I’d still like to know about this. (because I’d really like to give automatic refactoring a try in the next version)
I hope you haven’t forgotten this topic.
Thanks,
Tim
Hello Tim,
Sorry for the late reply in this thread.
It is a bit confusing as of what exactly the problem is, or what I can do to replicate what you have encountered.
I don’t see any reason why “boundGraphSerialization” being “modified”, will result in any issues, unless you actually want the prefab instance to be 1:1 with the prefab asset, in which case you can of course always “revert” the prefab instance.
Regarding the error, I was able to identify and fix this (thanks to another post in the forums).
To fix this, please open up ‘fsUnityObjectConverter’ and in ‘TryDeserialize’ method, ‘replace line of code:
if ( reference == null || storageType.RTIsAssignableFrom(reference.GetType()) ) {
with this:
if ( ReferenceEquals(reference, null) || storageType.RTIsAssignableFrom(reference.GetType()) ) {
Please let me know.
Thank you.
Join us on Discord: https://discord.gg/97q2Rjh
Thanks! I’ll try out your change and see if I can elaborate a bit on the first issue. (which is probably no issue)