Hi,
Here are some feedback/bugs encontered during my usage of the Behavior package, version 1.0.3 on Unity 6000.0.23f1.
When creating a new EventChannel in the Blackboard, the name is “New New <Your_event channel_type>” → word “New” is doubled, not the case with other Blackboard variables types(fixed in 1.0.4)- When creating a new action, you can’t choose the base class UnityEngine.Object in the variable type list. I had to choose UnityEngine.GameObject and then changed it to UnityEngine.Object once the C# script was created.
- I think we need to be able to pass raw UnityEngine.Object in conditions (even if it’s possible to bypass this issue using
[SerializeReference] public BlackboardVariable Object;instead of[SerializeReference] public BlackboardVariable<UnityEngine.Object> Object;):
– The functioninternal static bool IsBlackboardVariableTypeValid(FieldInfo field, ref Type invalidType)inNodeRegistry.cshas a mistake: the checkbool isObject = type.IsSubclassOf(typeof(UnityEngine.Object));should bebool isObject = type.IsSubclassOf(typeof(UnityEngine.Object)) || type == typeof(UnityEngine.Object);becausetypeof(UnityEngine.Object).IsSubclassOf(typeof(UnityEngine.Object))returnfalse. This prevent me to use a generic UnityEngine.Object variable in custom condition.
– After fixing the previous point locally, it’s still not possible to use generic Unity Object in conditions due to error:ArgumentException: Object of type 'Unity.Behavior.BlackboardVariable1[UnityEngine.GameObject]' cannot be converted to type 'Unity.Behavior.BlackboardVariable1[UnityEngine.Object]'. System.RuntimeType.CheckValue (System.Object value, System.Reflection.Binder binder, System.Globalization.CultureInfo culture, System.Reflection.BindingFlags invokeAttr). The conversion should be possible. - Creating an event with a C# keyword as variable name generate scripting error. Either block user creation with a warning or use @the_c_sharp_keyword in the generated script as variable name.
- When creating an event (or action) with a variable of type Button, the namespace (in this case UnityEngine.UI) isn’t added in the created script, resulting in script compilation error.
- When choosing the type in the wizard list, it doesn’t display the namespace, so you can have this issue, which one to choose? One is a custom script without namespace, the other is the UnityEngine.UI button.
- When typing in the inputfield during the action create wizard, using Ctrl+Z undo previous actions in the graph in the background instead of in the wizard. In my case, I deleted by mistake my action description and couldn’t use Ctrl+Z to undo my mistake, I had to redo mannually everything.
- After creating an event channel with 2 variables, I wanted to invert those variables order. I inverted everything in the script (including in the message). I had no errors, no warnings, but in the
public override void SendEventMessage(BlackboardVariable[] messageData)of my event channel, messageData[0] and messageData[1] are still given in the orignial order, thus creating error at runtime. In the graph window, everything is fine. I had to manually find wrong nodes in my graphs, delete and recreate them to reserialize their variables in correct order. - After creating an action with a gameObject variable, I decided to change it to a struct because I needed an additionnal boolean.
Script
using System;
using Unity.Behavior;
using UnityEngine;
using Action = Unity.Behavior.Action;
using Unity.Properties;
public struct TestStruct
{
public GameObject go;
public bool enable;
}
[Serializable, GeneratePropertyBag]
[NodeDescription(name: "TestStruct", story: "Testing [Struct]", category: "Action", id: "c31205f50f9e1d44fcc81c75a94d87b5")]
public partial class TestStructAction : Action
{
[SerializeReference] public BlackboardVariable<TestStruct> Struct;
protected override Status OnStart()
{
return Status.Running;
}
protected override Status OnUpdate()
{
return Status.Success;
}
protected override void OnEnd()
{
}
}
Now the graph window doesn’t display the graph anymore and spam this error in the console:
Error log
NullReferenceException: Object reference not set to an instance of an object
Unity.Behavior.ReflectionElement+<>c.b__5_0 (System.String variableName, Unity.Behavior.GraphFramework.SerializableType type) (at ./Packages/com.unity.behavior/Authoring/UI/AssetEditor/Nodes/ReflectionElement.cs:50)
Unity.Behavior.StoryElementUtility.FindAndAddField (System.String fieldName, System.Collections.Generic.List1[T] variables, UnityEngine.UIElements.VisualElement element, Unity.Behavior.StoryElementUtility+OnCreateLinkField onCreateLinkField, Unity.Behavior.StoryElementUtility+OnCreateComparisonElement comparisonElementCallback) (at ./Packages/com.unity.behavior/Authoring/UI/StoryElementUtility.cs:93) Unity.Behavior.StoryElementUtility.CreateStoryElement (System.String story, System.Collections.Generic.List1[T] variables, UnityEngine.UIElements.VisualElement element, Unity.Behavior.StoryElementUtility+OnCreateLinkField onCreateLinkField, Unity.Behavior.StoryElementUtility+OnCreateComparisonElement comparisonElementCallback) (at ./Packages/com.unity.behavior/Authoring/UI/StoryElementUtility.cs:35)
Unity.Behavior.ReflectionElement.CreateFields (Unity.Behavior.NodeInfo nodeInfo) (at ./Packages/com.unity.behavior/Authoring/UI/AssetEditor/Nodes/ReflectionElement.cs:47)
Unity.Behavior.ActionNodeUI.InitFromNodeInfo (Unity.Behavior.NodeInfo nodeInfo) (at ./Packages/com.unity.behavior/Authoring/UI/AssetEditor/Nodes/ActionNodeUI.cs:36)
Unity.Behavior.ActionNodeUI…ctor (Unity.Behavior.GraphFramework.NodeModel nodeModel) (at ./Packages/com.unity.behavior/Authoring/UI/AssetEditor/Nodes/ActionNodeUI.cs:25)
System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object parameters, System.Boolean wrapExceptions) (at <321eb2db7c6d43ea8fc39b54eaca3452>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.RuntimeConstructorInfo.InternalInvoke (System.Object obj, System.Object parameters, System.Boolean wrapExceptions) (at <321eb2db7c6d43ea8fc39b54eaca3452>:0)
System.Reflection.RuntimeConstructorInfo.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object parameters, System.Globalization.CultureInfo culture) (at <321eb2db7c6d43ea8fc39b54eaca3452>:0)
System.Reflection.RuntimeConstructorInfo.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object parameters, System.Globalization.CultureInfo culture) (at <321eb2db7c6d43ea8fc39b54eaca3452>:0)
System.RuntimeType.CreateInstanceImpl (System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object args, System.Globalization.CultureInfo culture, System.Object activationAttributes, System.Threading.StackCrawlMark& stackMark) (at <321eb2db7c6d43ea8fc39b54eaca3452>:0)
System.Activator.CreateInstance (System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object args, System.Globalization.CultureInfo culture, System.Object activationAttributes) (at <321eb2db7c6d43ea8fc39b54eaca3452>:0)
System.Activator.CreateInstance (System.Type type, System.Object args) (at <321eb2db7c6d43ea8fc39b54eaca3452>:0)
Unity.Behavior.GraphFramework.GraphViewState.CreateNodeUI (Unity.Behavior.GraphFramework.NodeModel nodeModel) (at ./Packages/com.unity.behavior/Tools/Graph/GraphView.cs:439)
Unity.Behavior.GraphFramework.GraphViewState.RefreshNodeUI (System.Boolean isDragging, System.Collections.Generic.List`1[T] nodesToRefresh) (at ./Packages/com.unity.behavior/Tools/Graph/GraphView.cs:370)
Unity.Behavior.GraphFramework.GraphViewState.RefreshFromAsset (System.Boolean isDragging) (at ./Packages/com.unity.behavior/Tools/Graph/GraphView.cs:244)
Unity.Behavior.GraphFramework.GraphView.RefreshFromAsset () (at ./Packages/com.unity.behavior/Tools/Graph/GraphView.cs:158)
UnityEngine.UIElements.VisualElement+SimpleScheduledItem.PerformTimerUpdate (UnityEngine.UIElements.TimerState state) (at <39dcd6cb83f94d46afd27f779648424a>:0)
UnityEngine.UIElements.TimerEventScheduler.UpdateScheduledEvents () (at <39dcd6cb83f94d46afd27f779648424a>:0)
UnityEngine.UIElements.UIElementsUtility.UnityEngine.UIElements.IUIElementsUtility.UpdateSchedulers () (at <39dcd6cb83f94d46afd27f779648424a>:0)
UnityEngine.UIElements.UIEventRegistration.UpdateSchedulers () (at <39dcd6cb83f94d46afd27f779648424a>:0)
UnityEditor.RetainedMode.UpdateSchedulers () (at :0)
It will be way better to take care of this error, display the graph with the “placeholder node” that user can delete, or fix the script.
Are custom structs usage in action/event channel supported? I tried to add [Serializable] and/or [GeneratePropertyBag] to my struct but it didn’t change anything. I backed off to simply use 2 variables in my action.
- I miss events to know the progress of the graph in the BehaviorAgent component. I would love to have a loopPointReached event similar to the VideoPlayer that is triggered when the graph execution ends or restart because repeat is activated.
When building for IL2CPP, a script called(fixed in 1.0.4, moved toBehaviorIL2CPPTypesis created at the root of the asset folder. Please let us move it where we want in the project (for meAssets/Scripts/Behavior) without failing at the next build. Other solution might be to automatically delete it after the build completed.Library/com.unity.behavior
)- The package decalare a dependency on newtonsoft json but don’t use it at all. It uses the Unity serialization package instead.
Thank you for this package. Fixing those quirks in the futur will improve user experience ![]()



