Skip to content
This repository has been archived by the owner on Oct 19, 2020. It is now read-only.

Code reflection

pixeltris edited this page Jun 6, 2019 · 5 revisions

There may be times when you want to access a Blueprint (or C++) class at runtime which wouldn't have normally been accessible from C#. The UE4 reflection system makes this possible.

In the following example the short path of a Blueprint class is used to find the class, get a int32 property named TestValue, and then set the value on all actors of that class type in the world.

[UFunction]
private void OnClick()
{
    UClass unrealClass = UClass.GetClass("SomeBlueprintClass_C");
    if (unrealClass != null)
    {
        UIntProperty intProperty = unrealClass.FindPropertyByName((FName)"TestValue") as UIntProperty;
        if (intProperty != null)
        {
            AActor[] actors = UGameplayStatics.GetAllActorsOfClass(this, unrealClass);
            foreach (AActor actor in actors)
            {
                int currentValue = intProperty.Accessor.GetValue(actor);
                intProperty.Accessor.SetValue(actor, currentValue + 1);
            }
        }
    }
}

DynamicInvoke

It's also possible to dynamically invoke functions using UObject.DynamicInvoke (by passing the function name) or UFunction.DynamicInvoke. It should be noted that these kind of function calls are much more expensive than other kinds of function calls.

The following example calls the function TestFunc defined in a Blueprint, where there is 1 input of type Integer which is passed by reference. The modified value is then printed to the screen.

[UFunction]
private void OnClick()
{
    UClass unrealClass = UClass.GetClass("SomeBlueprintClass_C");
    if (unrealClass != null)
    {
        UFunction function = unrealClass.FindFunctionByName((FName)"TestFunc", false);
        if (function != null)
        {
            AActor[] actors = UGameplayStatics.GetAllActorsOfClass(this, unrealClass);
            foreach (AActor actor in actors)
            {
                object[] args = { 0 };
                function.DynamicInvoke(actor, args);
                PrintString("TestFunc: " + args[0], FLinearColor.Red);
            }
        }
    }
}

Access Blueprint variables from a Blueprint object

This is similar to the first example. Here we have a Blueprint defined type and pass an instance of it in as a function parameter to a C# defined function.

We can't directly access the properties / functions defined in the Blueprint (as C# doesn't know about them). But you can use reflection to get this information if you really need to.

[UFunction, BlueprintCallable]
public void MyFunc(UObject obj)
{
    UClass unrealClass = obj.GetClass();
    if (unrealClass != null)
    {
        UIntProperty intProperty = unrealClass.FindPropertyByName((FName)"TestValue") as UIntProperty;
        if (intProperty != null)
        {
            int currentValue = intProperty.Accessor.GetValue(obj);
            intProperty.Accessor.SetValue(obj, currentValue + 1);
        }
    }
}