how save/load BehaviorSource json in Playmode

AlexxFree

New member
To save the state of the game to a file, you need to save / load the state of the behavior tree and its variables, how to do it? (not work in play mode)


public class TestBehaviorTreeSerialize : MonoBehaviour
{
public string Json;

public BehaviorTree behaviorTree;

private void Awake()
{
behaviorTree = GetComponent<BehaviorTree>();
}

[ContextMenu("Save")]
private void Save()
{
var source = behaviorTree.GetBehaviorSource();
Json = JsonUtility.ToJson(source);
}

[ContextMenu("Load")]
private void Load()
{
var source = JsonUtility.FromJson<BehaviorSource>(Json);
behaviorTree.enabled = false;
source.Initialize(behaviorTree);
if (source.CheckForSerialization(true))
{
behaviorTree.SetBehaviorSource(source);
}
behaviorTree.enabled = true;
}
}
 
Plase add call standad interface UnityEngine.ISerializationCallbackReceiver
by serialize/deserialize BehaviorSource

is to expand the data serialization, in variables, tasks and any objects

i am use runtime source

add to BinaryDeserialization.LoadFields to end

if (obj is ISerializationCallbackReceiver)
{
try
{
((ISerializationCallbackReceiver)obj).OnAfterDeserialize();
}
catch (Exception e)
{
Debug.LogException(e);
}
}

and to JSONDeserialization.DeserializeObject to end

if (obj is ISerializationCallbackReceiver)
{
try
{
((ISerializationCallbackReceiver)obj).OnAfterDeserialize();
}
catch (Exception e)
{
Debug.LogException(e);
}
}

but BehaviorSource exists only in Editor
i am decompile serializer and include him to runtime

add

private static void SerializeFields(
object obj,
ref Dictionary<string, object> dict,
ref List<UnityEngine.Object> unityObjects)
{
if (obj is ISerializationCallbackReceiver)
{
try
{
((ISerializationCallbackReceiver)obj).OnBeforeSerialize();
}
catch (Exception e)
{
Debug.LogException(e);
}
}

tis code work in runtime, but no OnBeforeSerialize call in editor



example use

[System.Serializable]
public class SharedMapObject : ISerializationCallbackReceiver
{
[NonSerialized]
public MapObject Obj;

[HideInInspector]
[SerializeField]
private int _idToSerialize = -1;

public void OnBeforeSerialize()
{
_idToSerialize = -1;
if (Obj != null && Obj.Entity != null)
{
_idToSerialize = Obj.Entity.Id;
}
}

public void OnAfterDeserialize()
{
if (_idToSerialize != -1 && WorldView.Instance != null)
{
Obj = WorldView.Instance.GetEntity(_idToSerialize) as MapObject;
}
}
}

[System.Serializable]
public class SharedMapObjectVariable : SharedVariable<SharedMapObject>
{
public static implicit operator SharedMapObjectVariable(SharedMapObject value)
{
return new SharedMapObjectVariable
{
mValue = value
};
}
}
 
Last edited:
Merging your threads. Right now it is not possible to save/load the tree at runtime. This is something that I have planned for version 2.

There's more to it than subscribing to the interface. In addition to the tasks/variables, the current active task, conditional aborts, variable values, etc need to also be serialized and this ends up being a lot of work in order to do properly. I have heard of others adding this using the runtime source, but they are doing it for specific tasks and not an overall general feature.
 
Top