Let’s say I have a Blackboard Parameter, “Foolist,” of type “List<GameObject>”
I have two actions that use it:
– Clear List (this one comes with NodeCanvas)
– The parameter type it takes is “IList”
– My Custom Action
– The parameter type it takes is “List<GameObject>”
If I attach this FSM/BT to another object, then “Promote Variables to Blackboard” what will happen is that “Foolist” will be created with a type of “IList” — which of course isn’t valid for My Custom Action.
Indeed, this is what will happen. The problem however here, is that there is no way for the “Promote Variables To Blackboard” functionality to know what type of variable is required in the end 🙁 .
The way the “Promote Variables To Blackboard” basically works is that it scans through all BBParameters in the graph in order.
As soon as a BBParameter with a name is encountered, a Variable with that name and with the type of that BBParameter is created in the blackboard.
If at a later time a BBParameter with the same name is encountered, it is basically skipped and does not alter the relevant Variable type.
It does not matter if it did or not however since the order the BBParameters are enounter is what matters most here.
I can’t really think of any way to “know” what the correct variable type to create should be based on how these are used in the graph BBParameters in relation to one another. I will take another look to see if I can come up with something, but if you have any ideas, by all means please let me know!
I was thinking there was an algorithm where you could walk through all usages of that BBParameter and find its strictest possible type that everyone else could use.
EG,
1
2
3
4
5
BBParameter<IList>
BBParameter<IEnumerable>
BBParameter<List<GameObject>>
So IList would be added to the Blackboard first. Since IList implements IEnumerable, we can keep IList. And, since List<GameObject> implements IList, we’d upgrade to List<GameObject>.
At some point (probably due to operator error changing types) this algorithm breaks down… I think its okay to log a warning message and default to whatever the last variable type was.
But I haven’t really thought through this algorithm.
Hey,
Thanks for the elaboration and your suggestion. It overally makes sense I think, but I need to think a bit more about this 🙂
I did make some tests you can also try out. If you want, please open up BlackboardSource.cs file and change the first clause in the AddVariable method in line #80 to be like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if(variables.ContainsKey(varName)){
varexisting=GetVariable(varName);
if(existing!=null){
if(existing.CanConvertTo(type)){
Debug.LogWarning(string.Format("<b>Blackboard:</b> Variable with name '{0}' already exists in blackboard '{1}'. Returning existing instead of new.",varName,this.name));
returnexisting;
}
if(existing.CanConvertFrom(type)){
Debug.LogWarning(string.Format("<b>Blackboard:</b> Variable with name '{0}' already exists in blackboard '{1}' but is of assignable type. Upgrading type and returning new variable.",varName,this.name));
RemoveVariable(varName);
}
}
}
This is just a test and not meant to really be used however 🙂 It does handle the specific case you showcased, but I will need to see what other kind of problems this may create.
Let me know what you think if you do test it.
Thank you!