Blueprint Macros and Macro Libraries

Blueprint Macros and Macro Libraries
A Blueprint Macro lets you reuse a set of nodes over and over, and can be created in any blueprint (using the Add Macro button on the ‘My Blueprint’ toolbar). You can also turn a selection into a macro by right-clicking on a selected node and using the ‘Collapse to Macro’ option. A macro works a lot like a collapsed graph; you can define arbitrary inputs and outputs, which will show up as pins whenever you place a macro instance. Here is an example of a macro named IsValid, which checks to see if an object pin is valid or not:

[IsValid macro declaration]

This macro can then be placed as an instance in another graph as ‘shorthand’ for the nodes it contains, allowing you to reuse code and hide complexity:

[IsValid macro usage]

Be sure to set the Description and Category on your macros. The description will show up as part of the tooltip on node instances, helping you remember what the macro is doing without having to open it up (though you can always peer inside by double-clicking on an instance). The category defines where the macro shows up in the graph action menu. You can also pick an instance color, which controls the color of the node title bar on instances (for example, we use white to indicate flow control nodes, matching the color of execution pins and wires).

DescriptionAndCategory.png

[Specifying Description and Category]

Macro Libraries
You can add macros to any blueprint, but normally they are only available for use in that Blueprint. In order to share a macro across many blueprints, you can add them to a Macro Library. There are a couple of built-in Macro Libraries in the Engine content directory (many features such as for loops are actually built using macros), but you should never edit content in the engine yourself, since future engine updates will stomp on your changes. Instead, create a Macro Library asset for your project using the content browser:

CB_Create_BlueprintMacroLibrary.png

[Creating a new Macro Library]

You’ll be asked to pick a parent class for your macro library just like a regular blueprint (Actor is a safe choice if you’re not sure what this means). This allows macros in the library to access variables and functions declared in the parent class as if they were in scope. For example, macros in a library based on Pawn can call GetController without being passed a Pawn, and they will only show up as options in the context menu for Blueprints based on Pawn or a more derived class like Character.

There’s also a tutorial that will walk you thru the Macro Library editor interface the first time you make one (it can be accessed again from the Help menu if you’ve already skipped it).


Feel free to reply with questions or comments below or join me on Twitter at @joatski](https://twitter.com/joatski).

I was just wondering how to make a macro library!
Great article!

Where do macro libraries get stored? So I can use them on another computer or if I re-intall UE4.

It’s a .uasset file on your disk, like any other asset. The actual path is where you chose to save it under the <Project>\Content folder.

How do you use variables in a macro library? When I create a variable in a macro library I get errors when I try to use it. There’s an extra “Target” input node that I see when I do drop a ‘get’ or ‘set’ pin from the local variable, but I don’t know what/if I need to hook this up to anything. It never seems to be a valid pin to hook anything to.

I’m pretty sure the target is looking for the blueprint it needs to communicate with.

Each macro library has a target class, you can access any variables in that class without providing a self pin. For example, in a library based on AActor you can directly read/write CustomTimeDilation. If you want to access a variable in something else, you’ll need a reference to that object to be able to wire into the Target pin (e.g., if you want to access a variable on a Pawn in an Actor library you should pass a pawn as an input into the macro, which can then be wired as the Target).

However, if you are talking about creating anonymous temporary variables inside of the macro, those are a bit clunky. Create a local variable from the menu, which has only an output pin. You can wire that directly to anything that needs to read the variable, and you wire it to the Variable pin of an Assign node whenever you need to write the variable.

Cheers,
Michael Noland

Thanks for the guidelines Michael, its very helpful. I have been trying function and macro libraries for a solution to my problem, but have been unsuccessful.

Here is my scenario:

I have a decal system done in blueprints. I want to encapsulate that system into a module so that I can plug into any weapon type such as an c++ interface. My problem comes down to the variables that I create to store for all of my nodes so that I can organize it easily.

My closest attempt was using a function library where I created all of the variables as local. I was able to call this function and the whole system works. However, when I create a second weapon it shares the same exact blueprints and variables as the other weapon. I would like to change some of the decal settings inside of the functions differently without affecting the other weapon.

So I went ahead and “expand” node inside of each weapon to create individual copies to manipulate separately. The problem with this technique is that the local variables disappear and have to be manually created and connected through the whole system tediously.

My final attempt was to go back to the Function Library and duplicate the Function into a new copy. I realize this technique could work by just duplicating a new function for each weapon.

I’d like to know if there is a better way of doing this? My purpose is to refactor my decal pack on the marketplace to be more user friendly and modular.

Thanks for any help on this! =)

Two options that come to mind:

Expose each variable as an input parameter to the macro/function. You can set default values for the inputs, but depending on how many variables you are talking about this may get unwieldy.

Create a custom Blueprint structure as your ‘configuration’ block. Again, you can set defaults on the basic struct, and you can declare a variable of that type in your weapon base class and the edit the values in the derived class. The user would wire up the configuration variable as an input to the function.

Cheers,
Michael Noland

Thanks for the suggestions. I like the struct idea so I will refactor around to make it work. =)

Thanks again Michael! I was able to do what I need to do. It was actually much simpler once you suggested the custom struct!

The result:

Cheers and Thanks!

Is it possible to create a project independent blueprint class / macro? That way we can reuse blueprints across projects easily (rather than right-click -> migrate), without the need to open up multiple projects.

There is no officially supported way right now, but I’ve got two suggestions for you as long as you accept that they’re not fully supported:

  • Create a new plugin and mark it as being capable of containing content. You can then save the asset in the content folder for that plugin, and include it in each project you want to use it with ( “CanContainContent” : true ).
  • Add it to the Engine Content folder. This is unsafe if using the launcher, and it will not be copied to new versions of the engine and will be deleted if you install a hotfix or ‘verify’ the installation.

Of the two, I’d certainly go with the plugin content approach.

Cheers,
Michael Noland

Cool, glad it worked out well.

Cheers,
Michael Noland

Thank you for the advice! I’ll add UE4 plugin development into my already huge library of things to learn :wink: Which I should probably do if I ever plan to attempt to create a voice to text/controller type of class thing-a-ma-bob.

Super cool advice! thanks!

I was wondering what would be best place to store game related constants. When reading this it totally struck me, macro library is something I need. Am I missing something or is it really this simple ?

https://cdn.pbrd.co/images/9t1OTeCgn.png

https://cdn.pbrd.co/images/9t38stduD.png

Option 1) Mark variables as “Config” and set default values in .ini file

Option 2) Place global vars in singleton like Game Instance, Game State, Game Mode.
Of course, you can mark vars in singleton as config vars too :wink:

As kjustynski mentioned, any game-wide variables should be stored in the Game *** classes.

If it is a single player, or if you don’t mind the variable data being stored on the client’s machine, then it should go into Game Mode. If the game is multiplayer, and you do care about where the variable is stored, then you want it in the Game State class.