+1
Under Review

Macro invocation from code API

LordZardeck 2 years ago updated by Lazlo Bonin (Lead Developer) 9 months ago 4

I'd like the ability for a non-technical person to create a macro asset, which can be execute from code without being contained in a graph

Bolt Version:
Unity Version:
Platform(s):
Scripting Backend:
.NET Version (API Compatibility Level):

This is actually what I've been asking for!

+1
Under Review

This is an example using internal APIs, but the general idea could be:

// Specify a macro however you want
FlowMacro macro = Resources.Load<FlowMacro>("...");
  
// Instantiate its graph via in-memory cloning (internal API)
FlowGraph graph = macro.graph.CloneViaFakeSerialization();
  
// Trigger the start event
graph.TriggerManualEvent<Start>(true);
  
// Fetch the value of any variable if you need:
var result = Variables.Graph(graph).Get("result");

With a graph like this one, result would have the value of "Hello world!":


Hi, just wanted to say it looks like 'TriggerManualEvent' does not exist anymore in FlowGraph. I would like to instantiate a macro in order to run events through it and keep the graph in memory for long-term storage of its variables.

Hi Te,

As I mentioned this is using internal APIs so they're not guaranteed to stay stable across versions.

But in new versions, you should be able to do it in a few different ways.

If you're using a Custom Event and the game is running, it's as easy as:

CustomEvent.Trigger("MyEventName", arg1, arg2, ...);

For other types of events, if the game is running and the event is registered on the event bus (most are), you can use EventBus.Trigger. For example:

 EventBus.Trigger(EventHooks.Start, new EmptyEventArgs());

If the game is not running or if the event is not registered on the event bus, it's a bit more complex. This should do it:

var reference = GraphReference.New(machine);
reference.TriggerEventHandler(hook => hook.name == "Start", new EmptyEventArgs(), parent => true, true);

The parameters for that method are, in order:

  1. A predicate to determine whether a given event should trigger based on its hook. Usually you want to compare the name.
  2. The event arguments to pass. Use EmptyEventArgs when there are none. It's a struct so creating one doesn't allocate memory.
  3. A predicate to determine whether the function should recurse down nested graphs based on their parent. In this case, I set it to always recurse.
  4. Whether to force the event to trigger, even if it isn't listening. This has to be true if you're in edit mode, because no events are listening yet.