I’m running into a problem where a Blackboard will lose the proper UnityEngine.Object references setup. The issue is strange and you’ll think it is some kind of user-error, but please read through.
Let’s start with this blackbaord:
1
2
3
[BB1]
[myVar1][type=CustomMonoBehaviour][value1]
[myVar2][type=CustomMonoBehaviour][value2]
CustomMonoBehaviour is simply a script file from my project. There are 2 variables in the BB, both of them assigned by dragging a game object onto the variable field.
For some BB, when the project recompiles, the BB variable value2 get set to value1.
1
2
3
[BB1]
[myVar1][type=CustomMonoBehaviour][value1]
[myVar2][type=CustomMonoBehaviour][value1]
Ok, it sounds like I’m crazy now, but I’ve spent a lot of time to figuring this out.
It boils down to jsUnityObjectConverter, in the Serialize function: database.Contains((UnityEngine.Object)instance) is used to determine if the current reference is already tracked. Under some conditions this will return TRUE when it shouldn’t. In the case of the BB above, the check value1 == value2 returns TRUE while a basic Debug.Log on the object shows they are different.
I don’t know what’s special about the moment when Unity recompiles but it certainly happens then (Serialize is called right after the project has compiled, that is also unclear why to me). Unity does internal serialization during recompile, play and build so I would believe this problem could happen then as well. I saw other posts on the forums that sound suspiciously similar to this: Button conditions lost when building application
I do not know either why it happens with some BB and not others, no idea. Clearly, I don’t have all the answer or even really understand what is going on, but there is an issue there.
I have a workaround. Actually, if you take a look at fsCyclicReferenceManager.cs in FullSerializer, you will notice the comment:
1
2
3
4
// We use the default ReferenceEquals when comparing two objects because
// custom objects may override equals methods. These overriden equals may
// treat equals differently; we want to serialize/deserialize the object
// graph *identically* to how it currently exists.
Unity is infamous for messing with the == and Equals() on gameobjects (see unity’s blog) so the idea is to use ReferenceEquals instead of the basic Equals (which is used by Contains/IndexOf).