# Blueprint Function Libraries

{% hint style="danger" %}

## <mark style="color:yellow;">A Warning</mark>

It is recommended not to use this method for externally released Plugins due to the order of operations on Unreal Startup. The general order on startup looks something like this:

1. Plugins are mounted
2. The Default Map is opened in the Editor
3. Any cached Editor Utility Widgets are reopened (EUWs that were open when the Editor was previously closed)
4. <mark style="color:yellow;">Python startup is run</mark>

Editor Actors in the default map and cached EUWs will load before Python initializes, resulting in Blueprint Compiler errors as the Python-generated BP Function Library doesn't exist yet:

```
LogBlueprint: Error: [AssetLog] C:\ue_projects\demo_project\Plugins\DevTools\Content\demo_tool.uasset: [Compiler] Could not find a function named "get_all_actors" in 'demo_tool'.
Make sure 'demo_tool' has been compiled for  Get All Actors
```

Making BP Function Libraries safer is covered here:

[making-bp-function-libraries-safer](https://bkortbus.gitbook.io/unreal-python-recipe-book/calling-python-from-blueprint/blueprint-function-libraries/making-bp-function-libraries-safer "mention")
{% endhint %}

***

## Declaring a BP Function Library class

We first need to create a class which will store all of our Blueprint Functions:

```python
import unreal

@unreal.uclass()
class PyDemoBPLibrary(unreal.BlueprintFunctionLibrary):
    """Blueprint functions declared in this class will be available in Editor"""
    # functions to follow...
```

This `PythonFunctionLibrary` class will be where all following function node examples are declared.

* The [@unreal.uclass()](https://docs.unrealengine.com/5.2/en-US/PythonAPI/module/unreal.html#unreal.uclass) decorator tells Unreal to expose it to the Editor
* The `PyDemoBPLibrary` class name is arbitrary, name it uniquely as you please!
* The [unreal.BlueprintFunctionLibrary](https://docs.unrealengine.com/5.2/en-US/PythonAPI/class/BlueprintFunctionLibrary.html#unreal.BlueprintFunctionLibrary) base class handles everything else

For the rest of this page we'll be adding functions to this class, any function added to this class will be made available to the Blueprint Graph.

***

## Decorator Overview

Functions are exposed to Unreal through decorators, there are two areas this page will focus on. This section is on the expected data: what's our input and what's our return. In the following section we'll cover how to organize and modify the behavior of the function via metadata.

### Basic function example

For all blueprint function this is our starting block:

```python
@unreal.ufunction(static=True)
def basic_function_test():
    """Python Blueprint Node -- run Python logic!"""
    print("Printed a message via Python!")
```

* [@unreal.ufunction()](https://docs.unrealengine.com/5.2/en-US/PythonAPI/module/unreal.html#unreal.ufunction) converts our Python function into a Blueprint Graph node, all of our settings will go in here.
* `static=True` tells Unreal that a `self` arg is not expected, all of our functions will have this
* Any Python docstring will also show in Unreal as the tool tip

<div align="left" data-full-width="false"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FldbCWkXynY8Zx0Fbfbpt%2Fimage.png?alt=media&#x26;token=014039f4-1b4b-4138-bdeb-abe1b86de321" alt=""><figcaption></figcaption></figure></div>

### Single Input / Output

To pass blueprint data to Python and back we must tell it what type of data we're expecting to provide/receive:

```python
@unreal.ufunction(static=True, params=[str])
def input_test(user_input = "cool!"):
    print(f"Provided input: {user_input}")
```

* `params` Is where we map the input type of each kwarg in sequential order
  * Any default kwarg values will display in the BP Graph node

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FF6p9k2EqbXApelciIhef%2Fimage.png?alt=media&#x26;token=5a1738cc-eb2e-4601-a7f1-e747b973371e" alt=""><figcaption></figcaption></figure></div>

```python
@unreal.ufunction(static=True, ret=str)
def return_test():
    return "cool!"
```

* `ret` Is where we tell it what return data type to expect

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FfNfKWjMaJvJ227VmUoiY%2Fimage.png?alt=media&#x26;token=5493078f-c856-4c0a-805a-e494d9047317" alt=""><figcaption></figcaption></figure></div>

### Multiple Input / Output

For inputs we can add to the list in sequential order of our Python function's params:

```python
@unreal.ufunction(static=True, params=[str, bool, int])
def multiple_input_test(in_str, in_bool, in_int):
    print(
        f"{in_str} ({type(in_str)}) | "
        f"{in_bool} ({type(in_bool)}) | "
        f"{in_int} ({type(in_int)})"
    )
```

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FqBJ81Tiepk24Th47sR12%2Fimage.png?alt=media&#x26;token=85ed8849-9e8e-4c83-94e8-5580ce966675" alt=""><figcaption></figcaption></figure></div>

```python
@unreal.ufunction(static=True, ret=(int, bool, str)) 
def multiple_returns_test():
    """Python Blueprint Node -- Return (str, bool, int)

    NOTE: the 'ret' decorator arg is reversed 
          from the actual python return, another option is to use:
          ret=(str, bool, int)[::-1]
    """
    return "Awesome", True, 5
```

* To return `str, bool, int` you tell unreal to expect `int, bool, str`
  * That's right, the return is reverse order!
  * Another option is to use `ret=(str, bool, int)[::-1]`  if we want to keep it visually consistent
* Unreal will also add a bogus `returnValue` bool that does nothing

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2Fxlwq8eaPlTJ3bjA4tgM0%2Fimage.png?alt=media&#x26;token=30b35ecc-56fc-4077-873e-4a63157e87bb" alt=""><figcaption></figcaption></figure></div>

### Handling Lists

When handling lists you must use the [unreal.Array(type)](https://docs.unrealengine.com/5.2/en-US/PythonAPI/class/Array.html#unreal.Array) class and declare its content:

```python
@unreal.ufunction(
    static=True, ret=unreal.Array(str), 
    params=[unreal.Array(str)]
)
def sort_string_list_test(in_list):
    return sorted(in_list)
```

* This example uses a list of `str` however it can be any data type, even `unreal.actor`!
* It's okay to return a python List as well, but if any of its contents are not `str` it will throw an error

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FGG7Fc4ILrjE1sZvqirVd%2Fimage.png?alt=media&#x26;token=72461dac-7dcc-44b8-8d81-984128d9e805" alt=""><figcaption></figcaption></figure></div>

### Pure functions (no exec in/out connections)

For getter functions we can use the `pure` flag:

```python
@unreal.ufunction(ret= str, pure=True, static=True)
def pure_function_test() -> str:
    return os.environ.get("USER", "unknown user")
```

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FbvOCDAGP8evnGe74ixHD%2Fimage.png?alt=media&#x26;token=9008817a-4b5b-4f15-ad67-4874fac5206d" alt=""><figcaption></figcaption></figure></div>

***

## Metadata Specifiers

This section covers the `meta` arg, which represents Metadata Specifiers. Given a dict of specifiers this flag grants further control over how the Blueprint node is organized, displayed, and behaves. To learn more about Metadata Specifiers [this Unreal page is a great resource](https://docs.unrealengine.com/5.2/en-US/metadata-specifiers-in-unreal-engine/).

### Category

The `Category` meta dict member controls how the function is organized in the right click menu:

```python
@unreal.ufunction(
    static=True, 
    meta=dict(Category="demo | category | sorting")
)
def meta_category_test():
    pass
```

* The `|` separator is how you set multiple depth levels in the menu

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FwxQ6iDcEAjdzyIvg0bNn%2Fimage.png?alt=media&#x26;token=73420d1e-fb22-4ef7-954e-293077d8aa99" alt=""><figcaption></figcaption></figure></div>

### Key Words

The `KeyWords` meta dict member registers additional words that may be used to find our function:

```python
@unreal.ufunction(
    static=True, 
    meta=dict(KeyWords="random arbitrary keywords")
)
def meta_keywords_test():
    pass
```

* You can find a function buy its name, its category, or any of its keywords

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FVLUUbDYJz2VGncYyZQbB%2Fimage.png?alt=media&#x26;token=5dc29991-f90e-49d2-b415-c30ec2b16825" alt=""><figcaption></figcaption></figure></div>

### Key Words

The `CompactNodeTitle` meta dict member tells our function to use a compact display in the Blueprint Graph:

```python
@unreal.ufunction(
    static=True, 
    meta=dict(CompactNodeTitle="UEPY")
)
def meta_compact_name_test():
    pass
```

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FBPC8o9uszRykhyMTFDMd%2Fimage.png?alt=media&#x26;token=e0159df6-ef1e-4371-8c33-d97b2541fe09" alt=""><figcaption></figcaption></figure></div>

### Default To Self

The `DefaultToSelf` meta dict member will populate the given kwarg with a reference to the containing BP Class that's calling it:

```python
@unreal.ufunction(
    static=True, 
    params=[unreal.Actor], 
    meta=dict(DefaultToSelf="target_object")
)
def meta_default_to_self_test(target_object):
    pass
```

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FQnc8a0twu5pB2HuDbKuv%2Fimage.png?alt=media&#x26;token=435c6701-a085-4331-8c71-2d69ae2aa0d9" alt=""><figcaption></figcaption></figure></div>

### Hide Pin (Fixes Multiple Returns)

The `HidePin` meta dict member tells Unreal to hide the desired pin, we can use this to fix the multiple returns example:

```python
@unreal.ufunction(
    static=True, 
    ret=(str, bool, int)[::-1], 
    meta=dict(HidePin="returnValue")
)
def multiple_returns_fixed_test():
    return "Awesome", True, 5
```

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2FQlo8GkBuUYy8nqGl31M5%2Fimage.png?alt=media&#x26;token=ff3bb8e1-33e1-435a-bbdb-ad0bf83963b6" alt=""><figcaption></figcaption></figure></div>

### Determines Output Type

The `DeterminesOutputType` meta dict member controls our function's return data type:

```python
@unreal.ufunction(
    static=True, 
    ret=unreal.Object,
    params=[unreal.Object],
    pure=True,
    meta=dict(DeterminesOutputType="object_to_match")
)
def match_object(object_to_match):
    pass
```

* This can help inform the Blueprint Graph when returning BP Assets created in the Editor
* `ret` and `params` still need to be provided, use an appropriate parent class

<div align="left"><figure><img src="https://368271246-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FStUBkBT2qJGKNkIZ6yc7%2Fuploads%2F6lLQrnDvUfhi6qgMNER3%2Fimage.png?alt=media&#x26;token=c08211fb-1873-4673-9f0d-75fda984a342" alt="" width="563"><figcaption></figcaption></figure></div>

***

## Advantages

The main <mark style="color:green;">advantage</mark> of this method is its verbosity, you can do so much more with this method than what's possible with Execute Python Script nodes.

## Disadvantages

A major <mark style="color:yellow;">disadvantage</mark> of this method is the instability covered in the warning section above. It is possible to mitigate the Editor Startup issues, but for public release projects it can't be guaranteed that other users will take the appropriate steps.

A minor <mark style="color:yellow;">inconvenience</mark> is that we have to provide our own `Success?` return, if we want it. If a Python error occurs during one of these nodes, it won't stop the Blueprint Graph from continuing on to the next node.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bkortbus.gitbook.io/unreal-python-recipe-book/calling-python-from-blueprint/blueprint-function-libraries.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
