I’m trying to modify Blackboard variables dynamically through C# at runtime. For example, I want to set a target position for a character to move to.
Currently, I couldn’t find relevant documentation explaining how to achieve this. I’ve tried using SetVariableValue, but it didn’t seem to work for my case.
Has anyone successfully implemented this or could point me in the right direction? Any examples or insights would be greatly appreciated!
What you can do (not sure if this the best way, I’m new to Behavior) is:
In your Behavior Graph Blackboard, create an ‘Event Channel type’
Make its story something like ‘Move target to position’, where position is a Vector2 or Vector3
Also create a Blackboard Variable (again Vector2 or Vector3) to receive your data, in your case target position.
In your Unity Assets, Create > Behavior > Event Channels > select your type
Back in the Graph, select Add, Events, Start on Event Message, drag in the event channel from the blackboard and set Assign position to the position variable you’ve created.
To debug, attach this node to a Log Variable action.
Now create a Monobehaviour script that does something like:
using UnityEngine;
using Unity.Behavior;
public class Foo : MonoBehavior
{
[SerializeField] private EventChannelBase eventChannel;
private BlackboardVariable<Vector3> targetPosition = new();
private BlackboardVariable[] messageData;
private void Start()
{
messageData = new BlackboardVariable[] { targetPosition };
}
public void SendEventMessage(Vector3 goal)
{
if (eventChannel == null)
{
Debug.LogError("EventChannel not found");
return;
}
targetPosition.Value = goal;
eventChannel.SendEventMessage(messageData);
}
}
Attach this script somewhere
In your editor, drag the Event Channel in the corresponding field
There are two versions, you can set the value by name or by guid. To find out the guid you can right click your variable in the blackboard and there is a copy Guid to clipboard function.
This was really useful to me, thanks!
I found a couple of issues, though.
The SendEventMessage needed the first parameter in the array to be a game object - it assumed this, and then the second parameter was the Vector3 and threw an index out of bounds error otherwise. Just went through again and it has only one parameter - not sure what I had done wrong!
I forgot to assign my “TargetAcquired” event variable in the blackboard to the actual event (if you see what I mean?)
But this was really useful, and something I feel I would never have arrived at via the manual!
I’ve successfully resolved the issue. It turns out that the Behavior Graph provides several methods to modify and transfer variables. I’ll summarize and share the approaches I’ve found:
The code provided by @david598scott worked perfectly. A few important notes:
The string argument must match the variable name in the Blackboard.
TValue is the type of the variable you wish to update.
(As a beginner, I initially had trouble understanding the definition and usage of TValue, but now it’s clearer.)
This method allows sending multiple variables simultaneously depending on how you set up your EventChannel Definition in the Blackboard. Here’s an example:
using UnityEngine;
using Unity.Behavior;
public class UpdateBlackboard : MonoBehaviour
{
private BehaviorGraphAgent behaviorGraphAgent;
private BlackboardVariable<ReceiveCommandEventChannel> setVariableEventChannel;
void Start()
{
behaviorGraphAgent = GetComponent<BehaviorGraphAgent>();
}
public void SetTarget(GameObject newTarget, Vector3 newPosition, LocationType newLoactionType)
{
// Using SendEventMessage
setVariableEventChannel.Value.SendEventMessage(newTarget, newPosition, newLoactionType);
// Using SetVariableValue
behaviorGraphAgent.BlackboardReference.SetVariableValue("Target", newTarget);
behaviorGraphAgent.BlackboardReference.SetVariableValue("TargetPosition", newPosition);
behaviorGraphAgent.BlackboardReference.SetVariableValue("TargetLocation", newLoactionType);
}
}