How do I use delegates in blueprints?

I can access interfaces in (for example) a spawned AI from the level blueprint by keeping a variable that stores the AI, and using that to access the interface.

However, I really want the AI to be able to call functions in the level blueprint. How do I do this sort of backwards accessing. In code I would use a delegate.

To give some context, I want all of the AI’s to maintain a global list of currently occupied cover volumes in one global place (the level blueprint) that they can query while deciding where to cover next - so they will have to be able to access functions in the level blueprint.

I notice that there’s a delegate output (little red box) on messages and was thinking that’s probably the thing to use but not quite sure how.

Why you get this idea that Level Blueprint is best place for global code? Level Blueprint is a piece of code that is attached to level, other level won’t have it, it is made for level scripts not game code it self. If you want good global place, best would be your GameMode class where you usally have your global game rules code

ok, good point, thank you, but it still doesn’t answer the question.

also the level blueprint was an example, the question is really just about delegates.

You have to create an event dispatcher in your class, then ‘bind’ that event when it’s spawned to a function in the global class.

There are actually a couple of ways to do this, but the basic premise is the same.

  1. Create an event dispatcher on the object that will be hosting the delegate. (For globals I would use Game Mode)
  2. Drag the dispatcher onto the edit graph, and select bind in the option window that pops up. This will create a bind delegate node on the graph.
  3. From the little red box on the bind node, drag off and select create event with this signature/name
  4. Edit the event.
  5. On the object that you want to call the event, select the appropriate call event dispatcher from the context menu.

The event that you have bound to the dispatcher will fire whenever the delegate is called. If you want to change the event, based on what is going on, you can create unbind event nodes on the event host and then rebind the event dispatcher. This is what I would do. The set up would require a bit more work, but in the end it would give you both flexibility and security to ensure that the wrong things aren’t screwing up your bindings.

(For a single flexible delegate)

  1. Create an Interface Blueprint for Game Mode named “IEventBinding”
  2. Set up two functions in the interface blueprint for IFChange_Case1 and IFChange_Case2 event
  3. In the Game Mode blueprint, implement the interface
  4. Create event dispatchers “Do Something”, EChangeCase1 and EChangeCase2(ones you will use for the interface functions.)
  5. In Game Mode, create an ‘Event Begin Play’ node, add two bind nodes for EchangeCase1 and EChangeCase2, and then drag off to create the events with the same name.
  6. In the bind event, drag off the exec pin and create an “Unbind” event for “DO Something”, then drag off the exec of the unbind event to clear the bindings.
  7. Drag off the Unbind event exec and create a Bind Event for “Do Something”.
  8. Drag off the red box and create an event node with the same name.
  9. Repeat step 6-8 for EChangeCase2.
  10. Add the code for the “Do Something” events for each case.
  11. In IFChange_Case1 on Game Mode, run any security you need, then drag off a dispatcher to call EChangeCase1
  12. Do the same for IFChange_Case2/EChangeCase2

The way it works:

The interface will serve as the gateway for actually changing which event is being executed by the delegate. it also gives you some room to make sure that the change is not happening when it is not supposed to. When the IFChage_Case1 calls EChangeCase1, it will clear the current binding for DoSomething, and then rebind it to the linked event, but it will do so without calling the event, which will keep it from firing when all you want to do is change it. The same will happen with IFChange_Case2.

Hope that helps.
Cheers,
Tony

just in case you like to avoid event and have just one spawner on stage…

1- Assume you have a Spawner blueprint class. This class make numbers of SpawnActors at runtime. Each Actor has a “Public Blueprint variable” named ID, which will assign to a number at “Spawn” time. Also, this class continuously generate random numbers on Tick and assign it to its public variable which is ID.
So in short, it Spawn couple of Actors with ID and has a random number generator on Tick event.

2- You need to add this class (spawner) to stage from editor. It should be there before running game.
3- In Actor class (which you re going to spawn), you need to use “Get All Actors of Class” on Tick and get your Spawner blueprint and put result in an array. It will be just one because you add just one spawner to stage. From that array simply get the first element and easy use public variable of your Spawner which is ID,.

you can use this in scenario like, if that random number match with the ID of you Actor, then you can play some functions thou.

In this approach you don’t need to use ANY event dispatcher.